識別兩個不同目錄之間的公共子目錄名稱並將其刪除

識別兩個不同目錄之間的公共子目錄名稱並將其刪除

我有兩個目錄dir1dir2其中有數百個子目錄depth 1。我只需要dir1和之間共有的子目錄名稱的信息,dir2然後系統地從 中刪除它們dir2。我不需要比較文件或文件內容。表演

diff -qr dir_one dir_two | sort

也產生檔名,我目前對此不感興趣。

答案1

對於您的用例,您可以避免確認公共目錄,因為rm -rf只是忽略不存在的目錄。

所以這就足夠了find 全部目錄dir1並從中刪除它們 dir2

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --

一些解釋。預設find會列印所有目錄,其完整路徑為dir1.因此,我們-printf只列印檔案名,不含前導目錄 (%f) 以及我們要刪除的其他路徑「dir2」。此外,我們使用空字節“\0”而不是換行符來終止字串,以使用xarg選項-0,這使得所有這些對於帶有空格的檔案名稱都是安全的。然後xargs將讀取標準輸入並rm透過添加所有字串作為參數來執行命令。

echo請注意,在實際刪除它們之前,您可以透過新增僅列印命令來測試命令列rm

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --

至僅清單您可以使用的常用目錄ls來取代rm(新增 2>/dev/null 以忽略不存在的目錄):

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null

答案2

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )

為了方便閱讀,使用換行符:

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
           <( cd dir2 && find -maxdepth 1 -type d | sort ) \
                | ( cd dir2 && xargs rm -rf )

解釋

find -maxdepth 1 -type d

僅列出沒有子目錄的目錄。

cd dir1 && find -maxdepth 1 -type d | sort

先更改目錄,然後列出目錄。

<( ... )

流程替代

comm -1 -3 <( ... ) <( ... )

取得第一個輸入和第二個輸入,並列印第二個輸入特有的行。實際上,這將列印位於dir2但不在 中的目錄dir1

... | ( cd dir2 && xargs rm -rf )

變更工作目錄,然後使用上一個指令的輸出作為參數dir2執行。rm -rf實際上,這將刪除位於dir2但不在 中的目錄dir1

首先透過移除管道xargs並檢查輸出來進行測試。

答案3

find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c  | egrep -v '^      1 ' | while read n de ; do echo rm -rfv dir2/$de ; done

正確時消除迴聲。

相關內容