我对 bash 脚本完全陌生,但我必须使用它。
我想循环遍历一个目录并将它们全部上传到远程服务器。然后我必须删除它们。
现在我遇到的问题如下: tcpdump 正在将 pcap 数据写入此目录(带有旋转文件),因此我不想上传最新文件。如何确保在迭代目录时,我将 100% 跳过最新的目录?由于创建文件和上传文件的过程是并行运行的,因此在开始上传的那一刻,可能会有一个“新”的最新文件。如果我跳过上传两个最新文件也没关系,但我不想上传现在最新的文件。
我尝试通过阅读“正常”循环的解决方案来学习 bash 脚本,但它的语法非常令人困惑,所以如果您能帮助我起点或向我指出初学者可以理解的部分解决方案,我会很高兴。
谢谢你!
PS:最新的文件也有最新的时间戳。
答案1
使用zsh
shell 并假设您的上传命令被调用upload
,并将所有文件作为命令行上的列表:
upload ./*(.Dom[2,-1])
glob 限定符(.Dom[2,-1]))
使前面的 globbing 模式 ( *
) 仅匹配常规文件(使用.
glob 限定符,并使用D
glob 限定符包含隐藏的此类文件),并且模式的扩展不会包含最近修改的文件(om
指示 shell按修改时间戳对文件进行排序,并[2,-1]
会在结果列表中选出除第一个之外的所有文件)。
然后,您可以使用相同的模式来删除传输的文件,或者您可以使用循环:
for name in ./*(.Dom[2,-1]); do
upload $name
rm -f $name
done
这应该处理所有类型的文件名,包括带有嵌入空格、制表符或换行符的文件名。
答案2
您可以使用 ls 的 -t 选项按修改对文件进行排序。与 tail 命令结合使用,您可以打印除第一个文件之外的所有文件。像这样的东西:
ls -t | tail -n +2
在循环中它可能看起来像这样:
for my_file in $(ls -t | tail -n +2); do upload $my_file; rm $my_file; done
答案3
# find the latest file
latestf="$(ls -t /directory/*|head -1)";
# loop over files now
for f in /directory/* ; do
if [[ "${f}" == "${latestf}" ]];then
echo "skipping file [${f}]";
else
echo "processing file [${f}]";
# your upload cmd here
fi
done