有一个bash命令来统计文件吗?

有一个bash命令来计算匹配模式的文件数量吗?

例如,我想获得一个目录中与这种模式匹配的所有文件的计数: log*

这个简单的单行程应该在任何shell中工作,而不仅仅是bash:

 ls -1q log* | wc -l 

ls -1q会为每个文件提供一行,即使它们包含空格或特殊字符(如换行符)。

输出被输送到wc -l,它计算行数。

你可以安全地使用bash(即不会被空格或\n的文件夹住)

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

您需要启用nullglob以便在没有文件匹配的情况下,您不会在$logfiles 数组中获得文字*.log

尝试这个:

 echo *.log | wc -w 

或者为了recursionsearch:

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

wc -w统计输出中的字数(bash将*.log扩展为与该模式匹配的空格分隔的文件列表),而wc -l将计算行数(每行打印一个结果)。


更新 :对于非recursionsearch,请执行以下操作:

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

这将规避lanzz提到的空间问题。

这里有很多答案,但有些不考虑

  • 包含空格,换行符或控制字符的文件名
  • 以连字符开头的文件名(设想一个名为-l的文件)
  • 空目录(即结果为0)
  • 非常大的目录(列出它们都可能会耗尽内存)

这是一个解决所有这些问题的解决scheme:

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

说明:

  • -U导致ls不对条目sorting,这意味着它不需要在内存中加载整个目录列表
  • -b为非graphics字符打印C样式转义符,导致换行符被打印为\n
  • 2>/dev/nullredirectstderr,以便如果有0个日志文件,则忽略错误消息。 (请注意, shopt -s nullglob会导致ls列出整个工作目录。)
  • wc -l在生成目录时会消耗目录列表,所以ls的输出在任何时候都不会在内存中。
  • --文件名与命令分开使用--以便不被理解为ls参数(如果删除了log*

shell 会将 log*扩展到完整的文件列表,如果文件很多,可能会耗尽内存,那么通过grep运行它会更好:

 ls -Ub1 | grep ^log | wc -l 

这最后一个处理非常大的文件目录,而不使用大量的内存(尽pipe它使用子shell)。

这个问题接受的答案是错误的,但我有低代表所以不能添加评论。

这个问题的正确答案是由Mat给出的:

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

被接受的答案的问题是wc -l计算换行符的数量,并且即使它们打印到terminal为'? 在'ls -l'的输出中。 这意味着当文件名包含换行符时,接受的答案FAILS。 我testing了build议的命令:

 ls -l log* | wc -l 

即使只有一个匹配名称恰好包含换行符的模式的文件,它也会错误地报告2的值。 例如:

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

如果你有很多文件,并且你不想使用优雅的shopt -s nullglob和bash数组解决scheme,只要不打印出文件名(可能包含换行符)。

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

这将find所有匹配log *且不以.*开始的文件.* – “not name。*”是重复的,但重要的是要注意“ls”的默认值是不显示点文件,但是find的默认值是包含它们。

这是一个正确的答案,并且可以处理任何types的文件名,因为文件名永远不会在命令之间传递。

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

这是我的一个class轮。

  file_count=$( shopt -s nullglob ; set -- $directory_to_search_inside/* ; echo $#) 
 ls -1 log* | wc -l 

这意味着每行列出一个文件,然后通过参数切换将其pipe理到字数统计命令来计算行数。