2012-07-03 33 views

回答

83

這簡單的一行應該在任何shell工作,不只是擊:

ls -1q log* | wc -l 

LS -1q會給你每個文件一行,即使它們包含空格或特殊字符,例如換行符。

輸出被傳送到wc -l,它計算行數。

+0

你只是*在另一面,但這工作thx很多 – hudi

+0

謝謝,更正以符合你的問題。 :) – Daniel

+5

我不會使用'-l',因爲每個文件上都需要'stat(2)'並且爲了計數而沒有添加任何內容。 – camh

27

試試這個:

echo *.log | wc -w 

或爲遞歸搜索:

find . -type f -name '*.log' | wc -l 

wc -w統計輸出中的字數(bash將*.log作爲與該模式匹配的空格分隔的文件列表),而wc -l將計算行數(find每行打印一個結果)。


更新:對於非遞歸搜索,這樣做:

find . -maxdepth 1 -type f -name '*.log' | wc -l 

這將規避lanzz提到的空間問題。

+3

'echo * .log | wc -w'會給出錯誤的結果,如果某些文件的名字中有空格 – lanzz

+0

@lanzz:True;沒想到那個! –

+0

我沒有使用空格文件 – hudi

32

你可以使用bash這樣做安全的(即不通過的文件被竊聽用空格或以他們的名義\n):

$ shopt -s nullglob 
$ logfiles=(*.log) 
$ echo ${#logfiles[@]} 
$ shopt -u nullglob 

您需要啓用nullglob,這樣你就不會得到字面*.log$logfilesarray如果沒有文件匹配。

1
ls -1 log* | wc -l 

這意味着每行列出一個文件,然後通過參數切換將其管道到字數統計命令,以便對行數進行計數。

+0

管道ls輸出時不需要「-1」選項。但是如果沒有文件匹配模式,你可能想要隱藏ls錯誤信息。我建議「ls log * 2>/dev/null | wc -l」。 – JohnMudd

3

如果你有很多文件,並且你不想使用優雅的shopt -s nullglob和bash數組解決方案,只要你不打印出文件名(可能包含新行)。

find -maxdepth 1 -name "log*" -not -name ".*" -printf '%i\n' | wc -l 

這會發現,比賽日誌*和不帶.*開始的所有文件 - 「沒有名字。*」是redunant,但要注意,對於「LS」的默認設置爲不很重要顯示點文件,但find的默認設置是包含它們。

這是一個正確的答案,並且可以處理任何類型的文件名,因爲文件名永遠不會在命令之間傳遞。

但是,shopt nullglob答案是最好的答案!

+0

你可能應該更新你的原始答案,而不是再次回答。 – qodeninja

+0

我認爲使用'find'與使用'ls'是解決問題的兩種不同方式。 'find'並不總是出現在機器上,但'ls'通常是, – mogsie

5

這個問題的接受答案是錯誤的,但我有低代表所以不能添加評論。

正確回答這個問題是由墊給出:

shopt -s nullglob 
logfiles=(*.log) 
echo ${#logfiles[@]} 

與接受答案的問題是,廁所-l計數的換行字符數,並計算他們,即使他們打印到終端作爲'?'在'ls -l'的輸出中。這意味着當文件名包含換行符時接受的答案失敗。我已經測試表明命令:

ls -l log* | wc -l 

,它錯誤地報告爲2的值,即使只有1個符合他的名字恰好包含一個換行符的模式文件。例如:

touch log$'\n'def 
ls log* -l | wc -l 
17

這裏很多答案,但有些不考慮與空格,換行,或控制字符

  • 文件名在其中,與連字號
  • 文件名(想象一個名叫-l文件)
  • 空目錄(即結果爲0)
  • 非常大的目錄(列出所有這些可能耗盡內存)

下面是處理所有這些解決方案:

ls 2>/dev/null -Ub1 -- log* | wc -l 

說明:

  • -U導致ls的條目不排序,這意味着它不需要加載整個目錄在內存中列出
  • -b打印非圖形字符的C樣式轉義,致命地導致換行符被打印爲\n
  • 2>/dev/null重定向stderr,以便如果有0個日誌文件,則忽略錯誤消息。 (請注意,shopt -s nullglob將導致ls列出整個工作目錄。)
  • wc -l消耗目錄列表,因爲它正在生成,所以ls的輸出永遠不會在內存中的任何時間點。
  • --文件名使用--以免被理解爲參數ls命令分離(如果log*被刪除)

外殼擴大log*到文件的完整列表,如果這是一個很大的文件,所以再通過grep的運行它這可能會耗盡內存會更好:的

ls -Ub1 | grep ^log | wc -l 

這最後一個處理非常大的目錄文件沒有使用大量的內存(儘管它使用子shell)。

+1

很好的答案,並且非常準確。 – raratiru

2

這是我的一個班輪。

file_count=$(shopt -s nullglob ; set -- $directory_to_search_inside/* ; echo $#) 
相關問題