我有多个文件在sftp服务器。我按照下面的代码使用unix shell脚本ksh从本地获取文件:
sftp user@hostname <<EOF cd file_path get file bye EOF
字符串我只需要从SFTP服务器这是7天的旧文件。我正在尝试下面的代码来获取7天前的文件,但没有任何工作:
get *.csv>7D
型它说文件找不到。
ih99xse11#
如果您没有该主机的SSH访问权限,这里有一个shellscript可以完成这项工作:
#! /bin/bash set -o nounset -o errexit FilePath='some/file/path' Target='user@host' Today="$(date '+%s')" GetList='' MaxAge=7 printf '%s\n' "cd $FilePath" 'ls -l' | sftp -b - "$Target" \ | sed --posix -e '1,2d' -e '/^d/d' -e 's/^\([^ ]\{1,\} *\)\{5\}//' -e 's/ */|/3' \ | { while read -r Line do File="${Line#*|}" AgeInSeconds="$(date -d "${Line%%|*}" '+%s')" AgeInDays="$(( (Today - AgeInSeconds) / 86400 ))" if test "$AgeInDays" -lt "$MaxAge" then GetList="$(printf '%s\n' "$File" "$GetList")" printf 'file %s is %u days old\n' "$File" "$AgeInDays" fi done IFS="${IFS#??}" GetCmd="$(printf 'ls -l %q\n' $GetList)" printf '%s\n' "cd $FilePath" "$GetCmd" | sftp -b - "$Target" }
字符串
此脚本已在Linux(Debian 11)环境下进行测试。如果你使用的是Mac或者 *BSD机器,那么date命令参数需要修改。该脚本还要求使用SSH公钥进行远程身份验证(无密码auth)。最后,如果远程文件名包含换行符(不太可能),脚本将无法工作。
printf '%s\n' "cd $FilePath" 'ls -l' | sftp -b - "$Target"
样品输出:
sftp> cd some/file/path sftp> ls -l -rw----r-- 1 someuser somegroup 44950 Oct 16 2015 file1.html -rw-r--r-- 1 someuser somegroup 2629188 Aug 28 2022 file2.pdf -rw------- 1 someuser somegroup 5 Jul 8 07:45 file3 -rw------- 1 someuser somegroup 5 Jul 8 07:49 file4 with spaces drwxr-xr-x 2 someuser somegroup 4 Sep 16 2022 somedir1 drwxr-xr-x 2 someuser somegroup 3 Jul 13 2022 somedir2 -rw----r-- 1 someuser somegroup 284 Mar 4 2019 file5.html -rw-r--r-- 1 someuser somegroup 414359930 May 23 05:25 file6.zip -rw-r--r-- 1 someuser somegroup 5873193 Aug 27 2022 file7.mp4 drwxr-xr-x 4 someuser somegroup 6 Aug 3 2022 somedir3 -r--r--r-- 1 someuser somegroup 14389839 Jan 1 2022 file8.zip drwxr-xr-x 2 someuser somegroup 3 Jul 14 2022 somedir4 -rw-r--r-- 1 someuser somegroup 4786464 Aug 28 2022 file9.pdf
型
sed --posix -e '1,2d'
-e '/^d/d'
-e 's/^\([^ ]\{1,\} *\)\{5\}//'
-e 's/ */|/3'
Aug 28 2022 file9.pdf
Aug 28 2022|file9.pdf
File="${Line#*|}"
"${Line%%|*}"
$(date -d "${Line%%|*}" '+%s')
(Today - AgeInSeconds) / 86400
GetList="$(printf '%s\n' "$File" "$GetList")"
IFS="${IFS#??}"
GetCmd="$(IFS="${IFS#??}" printf 'ls -l %s\n' $GetList)"
file1\nfile2\n
ls -l file1\nls -l file2\n
在当前状态下,脚本不会下载任何内容,而是会在远程服务器上下载不超过7天的ls -l文件。如果您决定使用该脚本(经过仔细测试),可以将GetCmd="$(IFS="${IFS#??}" printf 'ls -l %q\n' $GetList)"替换为GetCmd="$(IFS="${IFS#??}" printf 'get %q\n' $GetList)",以便实际下载文件。希望对你有帮助。
ls -l
GetCmd="$(IFS="${IFS#??}" printf 'ls -l %q\n' $GetList)"
GetCmd="$(IFS="${IFS#??}" printf 'get %q\n' $GetList)"
1条答案
按热度按时间ih99xse11#
如果您没有该主机的SSH访问权限,这里有一个shellscript可以完成这项工作:
字符串
警告:
此脚本已在Linux(Debian 11)环境下进行测试。如果你使用的是Mac或者 *BSD机器,那么date命令参数需要修改。
该脚本还要求使用SSH公钥进行远程身份验证(无密码auth)。
最后,如果远程文件名包含换行符(不太可能),脚本将无法工作。
说明
printf '%s\n' "cd $FilePath" 'ls -l' | sftp -b - "$Target"
将连接到远程主机,chdir到所需的目的地,并生成一个长列表。样品输出:
型
sed --posix -e '1,2d'
将删除前两行(SFTP命令)-e '/^d/d'
将删除目录项-e 's/^\([^ ]\{1,\} *\)\{5\}//'
将删除前5列(类型/权限,硬链接计数,用户,组,大小)-e 's/ */|/3'
将用管道字符替换第三组空格,使Aug 28 2022 file9.pdf
变为Aug 28 2022|file9.pdf
File="${Line#*|}"
删除每一行的开头,直到管道字符(因此只保留文件名)"${Line%%|*}"
在第一个管道字符的另一端执行相同的操作,因此只保留日期$(date -d "${Line%%|*}" '+%s')
将日期从epoch转换为秒(Today - AgeInSeconds) / 86400
将以秒为单位的年龄转换为天数(相对于当前日期)。86400 == 3600(一小时)* 24GetList="$(printf '%s\n' "$File" "$GetList")"
将候选文件名累积到一个变量中,用换行符分隔IFS="${IFS#??}"
:IFS通常为SPACE+TAB+NEWLINE。这里我们去掉前两个字符,只保留换行符作为扩展“GetList”变量时使用的标记分隔符GetCmd="$(IFS="${IFS#??}" printf 'ls -l %s\n' $GetList)"
将最终的远程命令(用换行符分隔)累积到一个变量中,因此file1\nfile2\n
变成ls -l file1\nls -l file2\n
在当前状态下,脚本不会下载任何内容,而是会在远程服务器上下载不超过7天的
ls -l
文件。如果您决定使用该脚本(经过仔细测试),可以将
GetCmd="$(IFS="${IFS#??}" printf 'ls -l %q\n' $GetList)"
替换为GetCmd="$(IFS="${IFS#??}" printf 'get %q\n' $GetList)"
,以便实际下载文件。希望对你有帮助。