Linux

如何遞歸地只複製文件夾和子文件夾中的文件?

  • February 26, 2019

/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,zshkshshell 中,-nt如果第一個操作數的修改時間戳比第二個操作數的修改時間戳更新,或者如果第二個操作數不存在,則測試為真。

但是,在dashshell 中,兩個文件都存在,並且第一個文件必須比第二個文件更新才能使測試為真(根據文件)。在這種情況下,這種差異不會成為問題。

yashshell 中,手冊中沒有指定如果任一文件不存在會發生什麼。

因此,在使用非標準工具時使用特定的 shell 是最安全的,即使在這種特定情況下,它可能無論如何都可以使用sh -c

(在這種情況下使用的缺點bash是它比較的時間戳只有一秒的解析度,但這是另一回事)

引用自:https://unix.stackexchange.com/questions/502979