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

时间:2013-03-05 05:18:10

标签: linux bash ubuntu

我可以按

列出所有目录
find ./ -type d

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

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

但这总结了

返回的总行数
find ./ -type d | xargs ls -l

有没有办法计算每个目录中的文件数?

17 个答案:

答案 0 :(得分:116)

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

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

答案 1 :(得分:81)

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

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

答案 2 :(得分:12)

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

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

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


如果您对当前目录的每个子目录中的文件计数感兴趣,计算任何子目录中的任何文件以及直接子目录中的文件,那么我将调整{ {1}}命令仅打印顶级目录:

sed

第一个模式捕获名称的开头,点,斜线,下一个斜杠的名称和斜杠,并用第一部分替换该行,所以:

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

替换为

./dir1/dir2/file1

第二个替换直接在当前目录中捕获文件;他们最后没有斜线,而是由./dir1/ 取代。然后,排序和计数仅适用于名称的数量。

答案 3 :(得分:11)

这是一种方法,但可能效率不高。

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

答案 4 :(得分:7)

其他人的解决方案都有一个缺点。

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

说明:

  • -type d:我们对目录感兴趣。
  • -readable:如果可能列出其中的文件,我们只需要它们。请注意,find在尝试搜索其中的更多目录时仍会发出错误,但这会阻止为其调用-exec
  • -exec sh -c BLAH sh {} ';':对于每个目录,运行此脚本片段,将$0设置为sh并将$1设置为文件名。
  • printf "%s " "$1":可移植且最小程度地打印目录名称,后跟只有一个空格,而不是换行符。
  • ls -1UA:按目录顺序列出文件,每行一个(以避免拖延管道),仅排除 特殊目录.和{{1} }
  • ..:计算行数

答案 5 :(得分:4)

这也可以通过循环ls而不是find

来完成

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

说明:

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

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

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

答案 6 :(得分:2)

使用find而不是du来对Sebastian's进行稍加修改的版本(以排除du必须执行且从未使用过的与文件大小有关的开销) :

 find ./ -mindepth 2 -type f | cut -d/ -f2 | sort | uniq -c | sort -nr

-mindepth 2参数用于排除当前目录中的文件。如果将其删除,则会看到很多类似以下内容的行:

  234 dir1
  123 dir2
    1 file1
    1 file2
    1 file3
      ...
    1 fileN

(非常类似于基于du的变体)

如果您确实还需要计算当前目录中的文件,请使用以下增强版本:

{ find ./ -mindepth 2 -type f | cut -d/ -f2 | sort && find ./ -maxdepth 1 -type f | cut -d/ -f1; } | uniq -c | sort -nr

输出将如下所示:

  234 dir1
  123 dir2
   42 .

答案 7 :(得分:1)

找到。 -type f -printf'%h \ n'|排序| uniq -c

举例说明:

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

答案 8 :(得分:1)

这应该返回目录名,后跟目录中的文件数。

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是必需的,因为-exec的{​​{1}}参数不允许执行bash函数,除非您明确调用bash,并且需要导出当前作用域中定义的函数明确地发布到新shell。

答案 9 :(得分:1)

find . -type f | cut -d/ -f2 | sort | uniq -c
  • find. -type f查找类型文件的所有项
  • cut -d/ -f2剪切出特定的文件夹
  • sort对文件夹名称列表进行排序
  • uniq -c返回对每个文件夹名称进行计数的次数

答案 10 :(得分:0)

我编辑了脚本,以排除分析的目录中的所有node_modules目录。

这可用于检查文件的项目数量是否超过文件查看器可以处理的最大数量。

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

要检查系统可以观看的最大文件数:

cat /proc/sys/fs/inotify/max_user_watches

node_modules文件夹应该在慢速系统中添加到IDE /编辑器排除的路径中,并且其他文件的数量理想上不应超过最大值(不过可以更改)。

答案 11 :(得分:0)

这可能是浏览目录结构并提供深度结果的另一种方法。

find . -type d  | awk '{print "echo -n \""$0"  \";ls -l "$0" | grep -v total | wc -l" }' | sh 

答案 12 :(得分:0)

一个超级快速的奇迹命令,它以递归方式遍历文件以计算目录中的图像数量并按图像扩展名组织输出:

find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'

积分:https://unix.stackexchange.com/a/386135/354980

答案 13 :(得分:0)

轻松递归查找给定类型的文件的方法。在这种情况下,当前目录中所有文件夹的.jpg文件:

find . -name *.jpg -print | wc -l

答案 14 :(得分:0)

我将@glenn jackman's answer和@pcarvalho的答案结合在一起(在注释列表中,pcarvalho的答案有问题,因为字符'`'(反引号)的额外样式控制功能)。 / p>

我的脚本可以接受路径作为起点,并将目录列表排序为ls -l它还可以处理“文件名中的空格”问题。

#!/bin/bash
OLD_IFS="$IFS"
IFS=$'\n'
for dir in $(find $1 -maxdepth 1 -type d | sort); 
do
    files=("$dir"/*)
    printf "%5d,%s\n" "${#files[@]}" "$dir"
done
FS="$OLD_IFS"

我在stackoverflow中的第一个答案,希望它能为您提供帮助^ _ ^

答案 15 :(得分:0)

我在这里与其他一些人一起尝试过,但当我只想要文件时,文件计数中包含了子文件夹。这将打印./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

答案 16 :(得分:-1)

这将给出整体计数。

for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'