Find

如果目錄中不存在文件名,則查找命令

  • May 3, 2022

我想如何顯示沒有特定文件的文件夾。但令人擔憂的是,文件名稱相同但情況不同。

案例研究:在工具目錄中,有包含readme/README文件的子目錄,其中一些沒有。例如

/toola/readme
/toolb/README
/toolc/ (does not have readme file)

我希望 find 命令使用此命令僅顯示 toolc 文件夾。

find . -maxdepth 2 ! -name '*readme*' -o ! -name '*README*' | awk -F "/" '{print $$2}' | uniq

但它不起作用。它顯示所有文件,因為toola沒有READMEtoolb沒有readme

您不能用於find查找不存在的文件。但是,您可以使用find查找目錄,然後測試給定的文件名是否存在於這些目錄中。

find用於查找目錄時,請確保使用-type d. 然後測試每個找到的目錄中的文件READMEreadme.

假設某些頂級目錄具有以下目錄層次結構projects

projects/
|-- toola
|   |-- doc
|   |-- readme
|   `-- src
|-- toolb
|   |-- doc
|   `-- src
|-- toolc
|   |-- README
|   |-- doc
|   `-- src
`-- toold
   |-- doc
   `-- src

用於find直接查找projects不包含READMEorreadme文件的目錄:

$ find projects -mindepth 1 -maxdepth 1 -type d \
   ! -exec test -f {}/README ';' \
   ! -exec test -f {}/readme ';' -print
projects/toolb
projects/toold

在這裡,我們直接在下面找到任何目錄projects,然後使用該test實用程序來確定找到的目錄中的哪一個不包含這兩個文件中的任何一個。

這完全等價於

find projects -mindepth 1 -maxdepth 1 -type d \
   -exec [ ! -f {}/README ] ';' \
   -exec [ ! -f {}/readme ] ';' -print

上述的另一種表述:

find projects -mindepth 1 -maxdepth 1 -type d -exec sh -c '
   for pathname do
       if [ ! -f "$pathname/README" ] &&
          [ ! -f "$pathname/readme" ]; then
           printf "%s\n" "$pathname"
       fi
   done' sh {} +

在這裡,我們讓一個小的內嵌 shell 腳本對這兩個文件進行實際測試,並列印不包含其中任何一個的目錄的路徑名。該find實用程序的作用類似於目錄路徑名的“路徑名生成器”,供內聯腳本迭代。

事實上,如果目錄結構是這樣的,我們可能會選擇完全不使用find

for pathname in projects/*/; do
   if [ ! -f "$pathname/README" ] &&
      [ ! -f "$pathname/readme" ]; then
       printf '%s\n' "$pathname"
   fi
done

請注意模式中的尾部斜杠projects/*/。正是這一點使模式只匹配目錄(或目錄的符號連結)。

這樣做和使用的區別在於find,在上面的 shell 循環中,我們將排除隱藏目錄project,並將包括目錄的符號連結。

在所有情況下,我們都會遍歷目錄的路徑名,並測試兩個文件名是否不存在。

唯一需要注意的是,-f對於指向正常文件的符號連結,該測試也是正確的。

有關的:

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