如何递归复制文件夹和子文件夹中的文件?

如何递归复制文件夹和子文件夹中的文件?

文件夹下/home有很多子文件夹,如下:

/home/user1
/home/user2/user_sub_2
/home/user3/user_sub_3/info_sub
/home/user4/INFO_FOLDER

我们想要将 下的所有文件递归/home复制到该/tmp/calculation文件夹​​中。所有文件应直接放入目标文件夹(不应创建子目录)。如果两个或多个文件具有相同的名称,则应将最近修改的文件复制到/tmp/calculation.

执行此操作的正确方法是什么?

答案1

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

例如,在bashzshkshshell 中,-nt如果第一个操作数的修改时间戳比第二个操作数的修改时间戳新,或者如果第二个操作数不存在,则测试为 true。

然而,在dash外壳中,两个都文件大多数存在,并且第一个文件必须比第二个文件更新才能使测试成立(根据文档)。在这种情况下,这种差异不会成为问题。

yashshell 中,手册中没有指定如果两个文件不存在会发生什么。

因此,在使用非标准设施时,使用特定的 shell 是最安全的,即使在这种特定情况下,它会大概sh -c无论如何已经合作过。

(这缺点在这个例子中使用的bash是它在比较的时间戳中只有一秒的分辨率,但那是另一个故事)

答案2

我尝试使用下面的命令,效果很好

for file in `find /home -type f | awk -F "/" '{print $NF}'`
do
    for dir in `find . -type d| sed "s/\.//g"| sed 's/$/\//g'`
    do
        sudo find $dir -type f -iname $file | awk '{print "ls -ltrh" " " $0}'
    done | sh | sed -n '$p'
done | awk '{print "cp -rvfp" " " $NF " " "/destinationlocationtocopy/"}' | sh

相关内容