如何统计每个目录中的文件数量?

我可以列出所有的目录

find ./ -type d 

我试图列出每个目录的内容,并通过使用以下命令来计算每个目录中的文件数量

 find ./ -type d | xargs ls -l | wc -l 

但是这总结了返回的行总数

 find ./ -type d | xargs ls -l 

有没有一种方法可以统计每个目录中的文件数量?

假设你有GNU find,让它find目录,让bash完成剩下的工作:

 find . -type d -print0 | while read -d '' -r dir; do files=("$dir"/*) printf "%5d files in directory %s\n" "${#files[@]}" "$dir" done 

这将打印当前目录级别的每个目录的文件数量:

 du -a | cut -d/ -f2 | sort | uniq -c | sort -nr 

您可以安排查找所有文件,删除文件名,只留下一行仅包含每个文件的目录名称,然后统计每个目录的显示次数:

 find . -type f | sed 's%/[^/]*$%%' | sort | uniq -c 

唯一的问题是如果你有任何包含换行符的文件名或目录名,这是不太可能的。 如果你真的不得不担心文件名或目录名中的换行符,我build议你find它们,并修正它们,使它们不包含换行符(并悄悄地说服他们错误的方式犯罪的一方)。


如果您对当前目录的每个子目录中的文件数目感兴趣,请计算任何子目录中的任何文件以及直接子目录中的文件,然后使用sed命令打印只有顶层目录:

 find . -type f | sed -e 's%^\(\./[^/]*/\).*$%\1%' -e 's%^\.\/[^/]*$%./%' | sort | uniq -c 

第一个模式捕获名称的起始点,点,斜线,直到下一个斜杠和斜杠的名称,并用第一个部分replace该行,如下所示:

 ./dir1/dir2/file1 

被replace

 ./dir1/ 

第二个replace直接在当前目录中捕获文件; 他们最后没有斜线,而是用./来代替。 然后,sorting和计数只适用于一些名称。

这是一个办法,但可能不是最有效的。

 find -type d -print0 | xargs -0 -n1 bash -c 'echo -n "$1:"; ls -1 "$1" | wc -l' -- 

给出这样的输出,目录名称后跟该目录中的条目数。 请注意,输出计数也将包括可能不是你想要的目录条目。

 ./c/fa/l:0 ./a:4 ./a/c:0 ./a/a:1 ./a/a/b:0 

其他人的解决scheme有一个缺点或另一个。

 find -type d -readable -exec sh -c 'printf "%s " "$1"; ls -1UA "$1" | wc -l' sh {} ';' 

说明:

  • -type d :我们对目录很感兴趣。
  • -readable :我们只希望他们能够列出文件。 请注意,当它试图在其中search更多的目录时, find仍然会发出一个错误,但是这会阻止为它们调用-exec
  • -exec sh -c BLAH sh {} ';' :对于每个目录,运行这个脚本片段, $0设置为sh$1设置为文件名。
  • printf "%s " "$1" :可移植且最低限度地打印目录名称,后面只有一个空格而不是换行符。
  • ls -1UA :按目录顺序列出每行一个文件(避免拖延pipe道), 排除特殊目录...
  • wc -l :统计行数

这应该返回目录名称,然后是目录中文件的数量。

 findfiles() { echo "$1" $(find "$1" -maxdepth 1 -type f | wc -l) } export -f findfiles find ./ -type d -exec bash -c 'findfiles "$0"' {} \; 

示例输出:

 ./ 6 ./foo 1 ./foo/bar 2 ./foo/bar/bazzz 0 ./foo/bar/baz 4 ./src 4 

export -f是必需的,因为find-exec参数不允许执行bash函数,除非明确调用bash,并且需要将当前作用域中定义的函数明确地导出到新的shell。

我住在这里,以备将来提醒

 ls |parallel 'echo {} && ls {}|wc -l' 

这也可以通过循环而不是查找来完成

for f in */; do echo "$f -> $(ls $f | wc -l)"; done

说明:

for f in */; – 遍历所有目录

do echo "$f -> – 打印出每个目录名称

$(ls $f | wc -l) – 为这个目录调用ls并计算行数

找 。 -type f -printf'%h \ n'| sorting| uniq -c

举例来说:

  5 . 4 ./aln 5 ./aln/iq 4 ./bs 4 ./ft 6 ./hot 

我尝试了一些其他的在这里,但最终与子文件夹包括在文件计数,当我只想要的文件。 这会打印./folder/path<tab>nnn文件的数量,不包括子文件夹,用于当前文件夹中的每个子文件夹。

 for d in `find . -type d -print` do echo -e "$d\t$(find $d -maxdepth 1 -type f -print | wc -l)" done