在/home
文件夹下,我们有许多子文件夹,如下所示:
/home/user1
/home/user2/user_sub_2
/home/user3/user_sub_3/info_sub
/home/user4/INFO_FOLDER
我们要将所有文件/home
递归地复制到该/tmp/calculation
文件夹中。所有文件应直接放置在目标文件夹中(不应创建任何子目录)。如果两个或多个文件具有相同的名称,则应将最新修改的文件复制到/tmp/calculation
。
什么是执行此操作的正确方法?
find /home ! -type d -exec bash -c '
for pathname do
if [ "$pathname" -nt "/tmp/calculation/${pathname##*/}" ]
then
cp "$pathname" /tmp/calculation
fi
done' bash {} +
这将在下找到所有非目录文件/home
,并且对于这些文件的批处理将调用一个短bash
脚本。
简短的bash
脚本将遍历当前路径名,并针对每个路径名进行测试,以-nt
测试当前文件是否比目标目录中的副本新(或那里是否不存在副本)。如果目标目录中的文件较旧或不存在,cp
则用于将当前文件复制到目标目录。
参数扩展${pathname##*/}
将删除实际文件名之前的所有目录路径,仅保留路径名的文件名部分。可以用代替$(basename "$pathname")
。
有关的:
大多不相关:
该-nt
测试是非标准测试。这就是为什么我选择使用bash
内部find
调用脚本的原因。使用sh -c
代替bash -c
可能会奏效,但是测试的语义在可能伪装成的shell之间可能略有不同sh
。
例如,在bash
,zsh
和ksh
壳,所述-nt
测试如果第一操作数具有修改的时间戳,在比所述第二操作数的更新,或者如果第二操作数不存在是真实的。
dash
但是,在外壳程序中,两个文件最多都存在,并且第一个文件必须比第二个文件新,才能使测试正确(根据文档)。在这种情况下,这种差异不会成为问题。
在yash
外壳中,手册中未指定如果两个文件都不存在会发生什么情况。
这是最安全的,因此使用非标准功能时要使用特定的外壳,即使在这种特殊情况下,将可能有工作sh -c
反正。
(在这种情况下使用的缺点bash
是,它所比较的时间戳只有一秒钟的分辨率,但这是另一回事了)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句