Find

如果找到文件,則修剪搜尋樹

  • December 13, 2021

我需要在一個相當大的目錄層次結構中搜尋名稱與特定文件名通配模式匹配的正常文件。層次結構是如此之大(非常深並且有一些巨大的目錄),以至於採取幼稚的方法需要很長時間:

find /top/dir -type f -name 'pattern'

pattern(像 . 的一些模式在哪裡*proj*.tgz。)

由於目錄結構的性質,我知道如果find在目錄中找到文件,我可以引入優化來修剪搜尋樹。例如,在特定目錄中找到一個或多個文件意味著我不需要檢查該特定目錄的任何子目錄以查找其他匹配項。

由於應用-prune到正常文件沒有做正確的事情,我不能只是做

find /top/dir -type f -name 'pattern' -prune

問題:如何避免搜尋包含與模式匹配的文件的目錄的子目錄?

可以為每個目錄呼叫一個內聯腳本。該腳本將檢查該模式是否與目錄中的任何正常文件匹配。如果模式匹配,它會輸出(在一般情況下,處理而不只是列印)匹配的路徑名並從搜尋樹中修剪父目錄:

find /top/dir -type d -exec zsh -c '
   set -- "$1"/pattern(.N)
   [[ $# -eq 0 ]] && exit 1
   printf "%s\n" "$@"' zsh {} \; -prune

我正在zsh為內聯腳本使用 shell 來訪問該 shell 的萬用字元。此處使用的限定符(.N), 確保只有正常文件與模式匹配,如果沒有匹配的文件則刪除模式。


用於bash內聯腳本:

find /top/dir -type d -exec bash -O nullglob -c '
   unset -v found
   for pathname in "$1"/pattern; do
       if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
           printf "%s\n" "$pathname"
           found=true
       fi
   done
   "${found-false}"' bash {} \; -prune

也就是說,讓內聯腳本循環遍歷特定目錄中與模式匹配的名稱,如果有任何名稱對應於正常文件,則對其進行處理並設置一個“標誌”。如果最後設置了標誌,則修剪父目錄。

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