首先:我为什么要尝试这个?因为我们需要下载一些文件并重命名以缩短带有日期“标记”的文件。远程文件的文件名非常大,并且无法更改(不是我们的 ftp)。
我正在尝试批量下载并重命名远程 ftp 服务器中的某些文件,而无需打开与我必须下载的每个文件的一个 ftp 连接。到目前为止,我可以使用 ftp 命令实现重命名和即时下载nmap
,将每个以“N”开头并以“.TXT”结尾的文件重命名为“N_date_time_stamp.TXT”
ftp -niv $url << FTP_COMMAND
user $user $password
cd $remotedir
nmap N*.TXT N_`date "+%H%M%N"`.TXT
mget N*
bye
FTP_COMMAND
问题是:nmap 对传递给 mget 的所有文件保持相同的 %N 值,并且它应该在每次下载时更改为当前纳秒值:
250 CWD command successful.
local: N_1054232349627.TXT remote: NO2346662345257245624572457245724562411125555341346134771345123461146-44.TXT
227 Entering Passive Mode (xxxxxxxxxxxxxxx).
125 Data connection already open; Transfer starting.
226 Transfer complete.
2220 bytes received in 0,0995 secs (22 Kbytes/sec)
local: N_1054232349627.TXT remote: NO2346662345257245624572457245724562411125555341346134771345123461146-45.TXT
227 Entering Passive Mode (xxxxxxxxxxxxxx).
125 Data connection already open; Transfer starting.
226 Transfer complete.
2220 bytes received in 0,107 secs (20 Kbytes/sec)
有没有办法nmap
在每次下载时更新?
答案1
和zsh
:
autoload zfinit
zfinit
zmodload zsh/datetime
files=N*.TXT
zfopen $host $user $passwd &&
zfcd $remotedir &&
zfrglob files &&
for f ($files) {
t=$EPOCHREALTIME
strftime -s ts %H%M%S ${t%.*}
ts=$ts.${t#*.}
zfgcp -Gt $f N_$ts.TXT
}
zfclose
答案2
ftp
我认为这不是执行此操作的合适工具。我会尝试lftp
一下。正如您编写的那样:
nmap N*.TXT N_`date "+%H%M%N"`.TXT
Get 被评估一次,然后扩展到当前日期,从那时起它仅用作扩展形式。你想要做的是让远程端为你做这个扩展,我不相信你可以用常规的 ftp 来做到这一点。
像这样的事情“可能”会起作用lftp
:
$ lftp -u user,password IP <<EOF
!whoami
quit 0
EOF
我目前无法访问 FTP 服务器,因此无法对此进行测试。如果它有效,那么您可以对其进行修改,以便该date
命令在远程服务器上运行。
参考
答案3
使用 FTP 完成复杂事情的简单方法就是不处理 FTP。将 FTP 资源挂载为文件系统。保险丝如今,即使在软件配置受限的服务器上也可以广泛使用。您可以使用曲线图挂载 FTP 目录。
mkdir /net/someftp.example.com
curlftpfs -o user=bob someftp.example.com /net/someftp.example.com
将 FTP 密码存储在~/.netrc
。
然后使用普通的 shell 命令复制具有所需名称的文件。我不推荐这种微秒日期方案,因为您依赖于足够快的时钟更新,这可能会出现问题,尤其是在脚本运行时调整时钟时。请改用计数器。
counter=10000
date=$(date +%Y%m%d-%H%M%S)
for x in /net/someftp.example.com/dir/N*.txt; do
cp -p "$x" "N-$date-${counter#1}.TXT"
counter=$((counter+1))
done
使用完 FTP 目录后,使用 卸载它fusermount -u /net/someftp.example.com
。
答案4
好吧,我根据 Stephane 和 slm 的答案做了某种混合实现。我无法使用 zsh,因为 zsh 是生产服务器,并且无法安装新的 shell,因此,我使用了已安装的 lftp:
解释:在第一个here_docs( FTPLISTGET
) 上连接ftp 服务器并列出文件( nlist
)。如果列表成功if [ $? -eq 0 ]
下载( ),则将一个文件一个一个地重命名为当前日期,格式为年、月、日、小时、分钟、纳秒)。有些 ftp 速度非常快,保存第二个可能会覆盖文件。
exec_ftp(){
# LIST
LIST_FTP=`lftp $protocol://$url << FTPLISTGET
user $user $pass
nlist
bye
FTPLISTGET`
# Check if list is not empty, proceed...
if [ $? -eq 0 ]; then
echo "$LIST_FTP" | while read file
do
DEST="N_$(date +%Y%m%d%H%M%N).TXT"
lftp $protocol://$url <<-DOWNLOAD
user $user $pass
cd $remotedir
get $file -o /home/user/$DEST
rm $file
bye
DOWNLOAD
echo "Done in $(date +%d/%m/%Y-%T)" >> /var/log/transfer_ftp.log
done
# If listing is not possible,
else
echo "FTP: $url user: $user - Cant reach host, or wrong credentials" >> /var/log/transfer_ftp_error.log
fi
}
编辑1:将反引号更改为$(...)
slm 建议的,并添加变量$protocol
。为什么?因为lftp可以下载并自动化sftp和ftps,这对我们来说非常好:)