
我想從三個不同的資料夾中尋找包含和排除某些文件的文件。
資料夾 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.log
或app1.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 …
,但不便攜。