如何遞歸地只複製文件夾和子文件夾中的文件?
在
/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
shell 中,-nt
如果第一個操作數的修改時間戳比第二個操作數的修改時間戳更新,或者如果第二個操作數不存在,則測試為真。但是,在
dash
shell 中,兩個文件都存在,並且第一個文件必須比第二個文件更新才能使測試為真(根據文件)。在這種情況下,這種差異不會成為問題。在
yash
shell 中,手冊中沒有指定如果任一文件不存在會發生什麼。因此,在使用非標準工具時使用特定的 shell 是最安全的,即使在這種特定情況下,它可能無論如何都可以使用
sh -c
。(在這種情況下使用的缺點
bash
是它比較的時間戳只有一秒的解析度,但這是另一回事)