Bash

find:如何有效地搜尋大文件名列表

  • September 17, 2021

我需要找到幾百個文件,其中的基本名稱由一些列表提供(我們稱之為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 中,則必須轉義或引用它們。

引用自:https://unix.stackexchange.com/questions/664352