在變數中尋找具有檔案名稱模式的 xargs rm

在變數中尋找具有檔案名稱模式的 xargs rm

像這樣的命令:

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

相關內容