unix sftp'ing一个文件与一个文件日期小于7天

oxf4rvwz  于 2023-08-04  发布在  Unix
关注(0)|答案(1)|浏览(149)

我有多个文件在sftp服务器。我按照下面的代码使用unix shell脚本ksh从本地获取文件:

sftp user@hostname <<EOF
cd file_path
get file
bye
EOF

字符串
我只需要从SFTP服务器这是7天的旧文件。
我正在尝试下面的代码来获取7天前的文件,但没有任何工作:

get *.csv>7D


它说文件找不到。

ih99xse1

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"将连接到远程主机,chdir到所需的目的地,并生成一个长列表。

样品输出:

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'将删除前两行(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(一小时)* 24
  • GetList="$(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)",以便实际下载文件。
希望对你有帮助。

相关问题