Bash
find:如何有效地搜尋大文件名列表
我需要找到幾百個文件,其中的基本名稱由一些列表提供(我們稱之為
baseNames
)。然後我需要搜尋這些基本名稱 + 三個給定的副檔名。*範例:*假設從輸入列表中提取的基本名稱之一是
FOO
,並且給定的副檔名是.txt
,.csv
,.py
。然後我需要找到FOO.txt
,FOO.csv
,FOO.py
.我的 bash 腳本中的目前方法如下:
for bn in ${baseNames}; do find ${searchDir} '(' -name "$bn.txt" -o -name "$bn.csv" -o -name "$bn.py" ')' done
這可行,但效率很低。對於每個基本名稱,我需要再次
find
整體執行searchDir
,其中包含相當多的文件,因此需要一段時間。
find
有沒有辦法通過選項或管道提供應該搜尋的文件列表?顯然我知道
-name ... -or
,但很明顯,如果我有幾百個文件,這種方法是不現實的。為簡單起見,您也可以將副檔名放在一邊。假設我有一個龐大的文件列表,我想搜尋這些文件作為find
.
使用數組。例如
#!/bin/bash baseNames=(FOO BAR BAZ) findNames=('(') for bn in "${baseNames[@]}"; do for ext in txt csv py; do findNames+=("$bn.$ext" '-o' '-name') done done # replace the final '-o' and '-name' in the array with a close parenthesis unset 'findNames[-1]' findNames[-1]=')' # If using a version of bash before v4.3, use: #unset 'findNames[${#findNames[@]}-1]' #findNames[${#findNames[@]}-1]=')' declare -p findNames
is的輸出
declare -p
(添加了一些換行符和空格以將其分解並使其更具可讀性):declare -a findNames=( [0]="(" [1]="-name" [2]="FOO.txt" [3]="-o" [4]="-name" [5]="FOO.csv" [6]="-o" [7]="-name" [8]="FOO.py" [9]="-o" [10]="-name" [11]="BAR.txt" [12]="-o" [13]="-name" [14]="BAR.csv" [15]="-o" [16]="-name" [17]="BAR.py" [18]="-o" [19]="-name" [20]="BAZ.txt" [21]="-o" [22]="-name" [23]="BAZ.csv" [24]="-o" [25]="-name" [26]="BAZ.py" [27]=")" )
要將數組與 一起使用
find
,您需要執行以下操作:searchDir="./" find "$searchDir" "${findNames[@]}"
這將導致執行以下 find 命令(為便於閱讀添加了換行符):
find ./ ( -name FOO.txt -o -name FOO.csv -o -name FOO.py \ -o -name BAR.txt -o -name BAR.csv -o -name BAR.py \ -o -name BAZ.txt -o -name BAZ.csv -o -name BAZ.py )
(
and)
不需要在這裡轉義,因為 shell 將它們視為文字參數(數組已經被 bash 擴展),而不是啟動子 shell 的指令。如果您將它們輸入到 shell 中,則必須轉義或引用它們。