從不同目錄中尋找文件,並包含和排除某些文件

從不同目錄中尋找文件,並包含和排除某些文件

我想從三個不同的資料夾中尋找包含和排除某些文件的文件。
資料夾 1:

  • 路徑:/var/www/app/var/log/
  • 僅排除:file1.log 和 file2.log

資料夾2:

  • 路徑:/var/log/web/log/
  • 僅包含:error.log

資料夾 3:

  • 路徑:/var/log/service/log/
  • 僅包含:app1.error.log & app2.error.log

在這種情況下,我如何從三個不同的資料夾中搜尋文件?

答案1

您可以使用 來執行此操作find。閱讀find有關排除和包括的一般用法:遞歸搜尋包含排除和包含的文件

您的問題涉及三個路徑,每個路徑都有不同的要求。人們可以在一次呼叫中指定許多起點find並建立一個表達式(例如使用-path),以便對不同的路徑執行不同的測試。這是可能的,但相當麻煩。一個簡單的方法是依序執行三個單獨的查找命令。

find /var/www/app/var/log ! -name file1.log         ! -name file2.log
find /var/log/web/log       -name error.log
find /var/log/service/log   -name app1.error.log -o   -name app2.error.log

筆記:

  • 上述指令中的多個空格只是為了強調它們的結構和相似之處。

  • 你說「我想找文件」。上面的命令會發現文件包括目錄類型的文件;特別是第一個指令將找到自己的起點 ( …/log)。要查找常規文件,只需您需要-type f.要尋找非目錄,只需您需要! -type d.

  • 如果file1.logapp1.error.log屬於目錄類型,則不清楚「包含」或「排除」是單獨指目錄還是指目錄及其下面的所有內容。這可能不是問題,因為很可能file1.log是您的設定中的常規檔案。

    根據記錄,上述每個指令都會遍歷其起點下的整個目錄樹。例如,如果file1.log是目錄類型,則! -name file1.log不會停止find測試file1.log/foo。要排除子樹,您需要-prune.

  • find遞歸地工作。讓 GNUfind不進入子目錄的最簡單方法是-maxdepth 1。非 GNU 實作可能不支援它。純粹的 POSIXfind 沒那麼簡單

    您標記了; Ubuntu 提供find開箱即用的 GNU,因此可以-maxdepth 1自由使用。

  • 正確使用-o 並不像你希望的那麼簡單

  • 如果涉及符號鏈接,請閱讀 中的有關-H-L選項man 1 find。您可能想使用其中之一。


考慮到這一切,我可以製作第三個命令的範例變體:或許更適合您的需求:

find /var/log/service/log/ -maxdepth 1 -type f \( -name app1.error.log -o -name app2.error.log \)

或 POSIX-ly(使答案對一般受眾更有用):

find /var/log/service/log/. \( -name . -o -prune \) -type f \( -name app1.error.log -o -name app2.error.log \)

後一個命令結束中起點的最後一個組成部分是.。這使我們能夠使用通用解決方案(我的意思是該形式-name . -o -prune不依賴起點路徑的真正有意義的部分)。另一方面,find將包含/.在每個路徑名中,您可能不希望如此。


運行三個find而不是一個並不會阻止您將結果通過管道傳輸到單個目的地(例如xargs):

{ find … ; find … ; find … ; } | xargs …

注意在 Ubuntu 中你可以這樣做find … -print0 | xargs -r0 …。這是更穩健find … -print | xargs …,但不便攜。

相關內容