使用 find 命令查找行數
考慮在https://cloud.r-project.org/src/base/R-3/R-3.4.4.tar.gz找到的 R 原始碼儲存庫。我將儲存庫解壓縮到一個文件夾中。現在,我想知道目錄中有多少行。所以,我嘗試了以下命令:
find . -type f -exec wc -l {} \+
產生 394968 但如果我嘗試以下命令:
find . -type f -exec cat {} \+ | wc -l
它產生1848857!
為什麼這兩個看似相似的
find
命令操作會產生如此截然不同的結果?而且,查找行數的正確方法是什麼,最好使用命令行實用程序而不是編寫一個小工具的腳本?
您提到的第一個命令
find . -type f -exec wc -l {} +
,實際上是說“wc -l
在盡可能多的文件上執行,直到所有文件都被處理”。這可以執行wc
多次!另一方面,
find . -type f -exec cat {} + | wc -l
可以執行cat
多次,但只會執行wc
一次。(更詳細地說,這是因為在這種情況下cat
由 呼叫find
,它可以並且確實決定執行它多次,而管道字元之後的部分wc -l
,超出了 的範圍find
,因此由您的殼,只有一次。)您說第一個命令“產生 394968”,但實際上沒有;在我的系統上,它的輸出以:
(Many more lines elided...) 23 ./po/Makefile.win 64 ./po/README 1 ./VERSION-NICK 97 ./README 258450 total
然而,通過添加
grep total
,可以看到它wc
確實執行了兩次:$ find . -type f -exec wc -l {} + | grep total 1590407 total 258450 total
而且,實際上,1590407 加上 258450 是 1848857,這與第二個命令一致。
find 手冊頁模糊地暗示了為什麼在命令版本中
wc
多次執行的解釋:find -exec wc +
-exec *command* {} +
此
-exec
操作變體在選定文件上執行指定命令,但命令行是通過在末尾附加每個選定文件名來建構的;該命令的呼叫總數將遠少於匹配文件的數量。命令行的建構方式與xargs
建構其命令行的方式大致相同。請注意這是如何說“比……少得多”而不是“只有一次”。xargs的 文件提示,
--max-chars
如果使用者未設置,則會自動設置其選項:
--max-chars=*max-chars*
-s *max-chars*
每個命令行最多使用*
max-chars
*字元,包括命令和初始參數以及參數字元串末尾的終止空值。最大允許值取決於系統,計算為 exec 的參數長度限制,減去環境的大小,減去 2048 字節的空間。如果此值大於 128KiB,則使用 128Kib 作為預設值;否則,預設值為最大值。這限制了一次呼叫可以傳遞多少個文件名
wc
,解釋了為什麼對於大量文件,wc
會發生多次呼叫,每個呼叫都在輸入的一個分區上操作。