像這樣的命令:
find /directory -type f -name "*.txt" -print | xargs rm
刪除.txt
目錄和子目錄中的每個文件,就可以了。但是,如果我們為檔案副檔名建立一個變數或數組,然後放置find
,例如,
TXT=(*.txt)
for ii in ${TXT[@]}; do
find /directory -type f -name $TXT -print | xargs rm
done
此命令不會刪除.txt
子目錄中的檔案。為什麼?如何更改第二個程式碼以刪除子目錄中的檔案?
PS:我使用了一個數組,因為我有多個檔案副檔名。
答案1
你的數組分配,
TXT=(*.txt)
會將*.txt
模式擴展到目前目錄中與該模式相符的檔案名稱清單。 shell 會在指派時執行此操作。這不是你想要的。您想要給出find
文字 string *.txt
,如下所示:
pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +
在這裡,我也擺脫了xargs rm
,而是rm
直接從執行find
。目前大多數的實作find
可以使用非標準-delete
來代替-exec rm {} +
:
pattern='*.txt'
find /directory -type f -name "$pattern" -delete
請注意,這裡不需要循環,因為我們只處理單一模式。另請注意,"$pattern"
呼叫中的引號find
很重要,否則該模式將在啟動前被當前目錄中所有符合的檔案名稱取代find
。
對於多種模式,您可以像這樣執行循環:
patterns=( '*.txt' '*.tmp' )
for pattern in "${patterns[@]}"; do
find /directory -type f -name "$pattern" -delete
done
數組賦值中的引號至關重要,因為它可以阻止 shell 將模式用作檔案名稱匹配模式。基於同樣的原因,對"${patterns[@]}"
和的引用"$pattern"
也同樣重要。
另一種方法是僅對 進行一次調用find
,即使您有多個模式。如果/directory
目錄層次結構很大,這會大大加快速度。以下程式碼透過建立一系列-name
測試來find
實現這一點:
patterns=( '*.txt' '*.tmp' )
name_tests=( )
for pattern in "${patterns[@]}"; do
name_tests+=( -o -name "$pattern" )
done
# "${name_tests[@]:1}" removes the initial "-o", which shouldn't be there.
name_tests=( '(' "${name_tests[@]:1}" ')' )
find /directory -type f "${name_tests[@]}" -delete
在上面的腳本中,最後執行的實際命令將是
find /directory -type f '(' -name '*.txt' -o -name '*.tmp' ')' -delete
...這將刪除所有具有文件名後綴的常規文件.txt
或者 .tmp
目錄中或目錄下的任何位置/directory
。