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

我可以列出所有的目录

find ./ -type d

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

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

返回的行总数

find ./ -type d | xargs ls -l

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

161069 次浏览

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

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是必需的,因为除非显式调用 bash,否则 find-exec参数不允许执行 bash 函数,并且需要显式地将当前范围中定义的函数导出到新的 shell。

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

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

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


如果你对工作目录的每个子目录中的文件计数感兴趣,计算任何子目录中的任何文件以及直接子目录中的文件,那么我会修改 sed命令,只打印顶级目录:

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

第一个模式捕获名称的开头、点、斜杠、直到下一个斜杠和斜杠的名称,并用第一个部分替换行,因此:

./dir1/dir2/file1

取而代之的是

./dir1/

第二个替换直接在工作目录中捕获文件,它们在末尾没有斜杠,并且那些文件被 ./替换。然后,排序和计数仅对名称的数量进行操作。

这里有一种方法,但可能不是最有效的。

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

假设您有 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

这会显示工作目录级别的每个目录的文件计数:

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

每个人的解决方案都有这样或那样的缺点。

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

说明:

  • 我们对目录感兴趣。
  • 我们只需要它们,如果它是 有可能列出其中的文件。请注意,当 find尝试在其中搜索更多目录时,仍然会发生错误,但这会阻止为这些目录调用 -exec
  • 对于每个目录,运行这个脚本片段,将 $0设置为 sh,将 $1设置为文件名。
  • printf "%s " "$1": 可移植地、最小限度地打印目录名,后面只加一个空格,不加换行符。
  • ls -1UA: 按目录顺序列出文件,每行一个(以避免延迟管道) ,不包括 只有的特殊目录 ...
  • 数数台词

输入 f-printf’% h n’| sort | uniq-c

例如:

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

这也可以通过循环代替 find 来完成

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

说明:

在所有目录上循环

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

$(ls $f | wc -l)-对此目录和计数行调用 ls

我在这里尝试了其他一些文件,但结果是当我只想要文件时,文件计数中包含了子文件夹。这将为当前文件夹中的每个子文件夹打印包含文件数(不包括子文件夹)的 ./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

这将给出总计数。

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

使用 find而不是 du塞巴斯蒂安的答案稍作修改(以排除 du必须执行但从未使用的与文件大小相关的开销) :

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

参数用于排除工作目录中的文件。如果你删除它,你会看到如下的一堆行:

  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 .

我结合了 @ Glenn Jackman 的回答和@pcarvalho 的答案(在评论列表中,pcarvalho 的答案有些问题,因为字符‘ `’(反勾)的额外样式控制功能)。

我的脚本可以接受 path 作为增量,并将目录列表排序为 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 中的第一个答案,我希望它能帮助某人 ^ _ ^

递归查找给定类型的文件的简单方法。在这种情况下。工作目录中所有文件夹的 jpg 文件:

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

find . -type f | cut -d/ -f2 | sort | uniq -c
  • 在当前文件夹和子文件夹中查找类型为 file的所有项
  • 裁剪 cut -d/ -f2的特定文件夹
  • sort对文件夹名列表进行排序
  • 返回每个文件夹名被计数的次数

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

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

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

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

我编辑这个脚本是为了排除被分析的目录中的所有 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/编辑器排除路径在慢系统,其他文件计数不应该理想地超过最大值(这可以改变)。

我的天,为什么这么复杂的命令

find whatever_folder | wc -l

我的回答是有点不同,由于选择的发现,你实际上可以更加灵活。试试看:

find . -type f -printf "%h\n" | sort | uniq -c

使用“% h”选项到“-printf”,find 只打印它找到的文件的目录。然后用“ uniq-c”进行排序和计数。这将打印每个目录中具有相同目录的搜索结果条目的数量。

在 find 上使用进一步的选项,可以更加灵活。例如,要了解在某个特定日期修改了哪个目录中的多少个文件,请使用:

find . -newermt "2022-01-01 00:00:00" -type f -printf "%TY-%Tm-%Td %h\n" | sort | uniq -c

这会查找自1以来修改过的所有文件。2022年1月,打印(使用“-printf”)修改日期和目录,然后对它们进行排序和计数。在这个示例中,结果中的每一行都有文件数、修改日期(没有时间)和目录。

请注意,我认为“-printf”可能不是在 find 的所有版本中都可用。

简易方法:

/| grep“ Search _ file. txt”| cut-d”/”-f2 | sort | uniq-c