146

我可以列出所有目录

find ./ -type d

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

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

但这总结了返回的总行数

find ./ -type d | xargs ls -l

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

4

19 回答 19

258

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

du -a | cut -d/ -f2 | sort | uniq -c | sort -nr
于 2016-09-21T17:26:19.617 回答
143

假设你有 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
于 2013-03-05T10:40:55.910 回答
71
find . -type f | cut -d/ -f2 | sort | uniq -c
  • find . -type ffile在当前文件夹和子文件夹中查找该类型的所有项目
  • cut -d/ -f2剪下他们的特定文件夹
  • sort对文件夹名称列表进行排序
  • uniq -c返回每个文件夹名称的计数次数
于 2019-01-22T10:06:05.330 回答
20

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

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/

第二个replace直接捕获当前目录下的文件;他们最后没有斜线,而那些被替换为./. 然后排序和计数仅适用于名称的数量。

于 2013-03-05T05:27:12.763 回答
14

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

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
于 2013-03-05T05:29:15.897 回答
12

塞巴斯蒂安答案的略微修改版本,使用find代替(以排除必须执行且从未使用过du的与文件大小相关的开销):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 .
于 2018-07-23T13:00:31.030 回答
8

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

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: 按目录顺序列出文件,每行一个(以避免阻塞管道),排除特殊目录...
  • wc -l: 计​​算行数
于 2016-09-21T19:14:49.350 回答
6

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

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

解释:

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

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

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

于 2017-07-16T21:21:02.057 回答
5

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

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不允许find执行 bash 函数,除非您显式调用 bash,并且您需要将当前作用域中定义的函数显式导出到新的 shell。

于 2013-03-05T05:24:15.743 回答
2

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

find . -type d  | awk '{print "echo -n \""$0"  \";ls -l "$0" | grep -v total | wc -l" }' | sh 
于 2019-11-20T20:12:53.073 回答
2

我结合了@glenn jackman 的答案和@pcarvalho 的答案(在评论列表中,pcarvalho 的答案有问题,因为字符' ' (反引号)的额外样式控制功能

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

于 2018-11-17T11:54:54.050 回答
1

我的回答有点不同,由于 find 的选项,您实际上可以更加灵活。试试看嘛:

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

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

在 find 上使用更多选项,您可以更加灵活。例如,要了解某个目录在某个日期修改了多少文件,请使用:

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

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

请注意,我认为并非所有版本的 find 都提供“-printf”。

于 2022-02-10T19:43:19.780 回答
1

寻找 。-type f -printf '%h\n' | 排序 | 唯一的-c

例如:

  5 .
  4 ./aln
  5 ./aln/iq
  4 ./bs
  4 ./ft
  6 ./hot
于 2017-07-02T21:51:20.060 回答
1

我在这里尝试了其他一些,但当我只想要文件时,最终文件计数中包含了子文件夹。这将打印./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
于 2017-11-02T23:10:06.910 回答
0

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

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

于 2018-12-27T12:37:53.427 回答
0

这将给出总计数。

for file in */; do echo "$file -> $(ls $file | wc -l)"; done | cut -d ' ' -f 3| py --ji -l 'numpy.sum(l)'
于 2018-05-20T11:21:52.743 回答
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

于 2019-08-08T08:41:24.383 回答
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/编辑器排除路径中,并且其他文件数理想情况下不应超过最大值(尽管可以更改)。

于 2020-08-15T10:22:53.227 回答
-2

天哪,为什么复杂的命令。只需使用类似的东西

find whatever_folder | wc -l
于 2021-08-16T15:39:33.203 回答