find -exec + 與 find | xargs:選擇哪一個?

find -exec + 與 find | xargs:選擇哪一個?

我知道 可以-exec選擇+模仿 的行為xargs。是否存在您更喜歡其中一種形式而不是另一種形式的情況?

我個人更喜歡第一種形式,即使只是為了避免使用管道。我想開發者肯定find已經做了適當的優化。我對麼?

答案1

安全地透過管道傳輸檔案名稱xargs需要您find支援該-print0選項並且您xargs有相應的選項來讀取它(--null-0)。否則,名稱中包含不可列印字元、反斜線、引號或空格的檔案名稱可能會導致意外行為。另一方面,find -exec {} +是在POSIXfind規範,所以它是便攜式的,並且它與 一樣安全find -print0 | xargs -0,並且絕對比 更安全find | xargs。我會推薦絕不find | xargs沒有做-print0

答案2

您可能想要連結呼叫來查找(曾經,當您了解到這是可能的,這可能是今天)。當然,這只有在您繼續尋找時才有可能。一旦你通過管道傳輸到 xargs,它就超出了範圍。

小例子,兩個檔案 a.lst 和 b.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

這裡沒有技巧 - 只是事實是兩者都包含“fuddel”,但只有一個包含“fiddel”。

假設我們不知道這一點。我們搜尋一個符合 2 個條件的文件:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

好吧,也許您知道 grep 或其他程式將兩個字串作為條件傳遞的語法,但這不是重點。每個可以傳回 true 或 false 的程式(給定檔案作為參數)都可以在這裡使用 - grep 只是一個流行的範例。

請注意,您可以關注查找-執行與其他查找命令一起使用,例如-ls或者-刪除或類似的東西。請注意,delete 不僅可以執行 rm(刪除檔案)操作,還可以執行 rmdir(刪除目錄)操作。

只要沒有另外指定(即帶有開關-or(和括號(需要屏蔽))),這樣的鏈就會被讀取為命令的 AND 組合。

所以你不會離開查找鏈,這是一件很方便的事。我沒有看到使用 -xargs 的任何優勢,因為您在傳遞文件時必須小心,這是 find 不需要做的事情 - 它會自動處理將每個文件作為單一參數傳遞給您。

如果您認為需要對發現的東西進行一些掩蓋{} 大括號,請隨時訪問我的問題,要求提供證據。我的斷言是:你不知道。

答案3

如果您使用該-exec ... ;形式(記住轉義分號),則每個檔案名稱執行該命令一次。如果使用-print0 | xargs -0,則每個檔案名稱運行多個命令。您絕對應該使用該-exec +表單,它將多個文件放在一個命令行中,並且在涉及大量文件時要快得多。

using 的一大優點xargs是能夠使用 並行執行多個指令xargs -P。在多核心系統上,這可以節省大量時間。

答案4

關於性能,我認為這-exec … +會更好,因為它是一個完成所有工作的單一工具,但是GNU findutil 文件的一部分-exec … +在某些情況下可能效率較低:

[查找與-exec … +]可能比 的某些用途效率低xargs;例如,xargs允許在上一個命令仍在執行的同時建置新的命令列,並允許您指定多個要並行運行的命令。然而,該find ... -exec ... +結構具有廣泛的可移植性的優點。 GNU findutils-exec ... +直到版本 4.2.12 才支援 ' '[2005 年 1 月];原因之一是-print0無論如何它已經有了“ ”動作。

我不太確定這意味著什麼,所以我在聊天中詢問德羅伯特解釋為:

find可能可以在運行時繼續搜索下一批文件-exec … +,但事實並非如此。
find … | xargs …確實如此,因為查找是一個不同的進程,而且它會一直運行直到管道緩衝區填滿

(我自己格式化的。)

所以就是這樣。但如果效能真的很重要,您就必須進行實際的基準測試,或者甚至問自己是否願意在這種情況下使用 shell。

在這個網站上,我認為最好建議人們-exec … +盡可能使用該表單,因為它更簡單,並且出於此處其他答案中提到的原因(例如,無需考慮太多即可處理奇怪的文件名)。

相關內容