如何通过目录递归计算所有文件


47

我想查看子目录中有多少文件,以找出所有inode用法在系统上的位置。有点像我会这样做以节省空间

du -sh /*

这将为我提供根目录中使用的空间,但是在这种情况下,我需要文件的数量而不是大小。



我认为“子目录中的子目录中有多少个文件”是一个令人困惑的构造。如果更清楚地说明您想要什么,您可能会得到符合要求的答案。
史蒂文D

@Steven随时可以重写它...我想我的示例du -sh /*很清楚地说明了我希望计数如何工作。同样,只计算文件而不是字节。
xenoterracide

正如您提到的inode用法一样,我不知道您是要计算文件数量还是要使用的inode数量。当文件系统中存在硬链接时,两者是不同的。大多数(如果不是全部)答案给出文件的数量。不要在Apple Time Machine备份磁盘上使用它们。
mouviciel 2010年

@mouviciel并没有在备份磁盘上使用它,是的,我想它们可能有所不同,但是在我所处的环境中,硬链接很少,从技术上来说,我只需要对此有所了解。找出有人在哪里烧坏inode配额。
xenoterracide 2010年

Answers:


60
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

感谢Gilles和xenoterracide修复了安全性/兼容性。

第一部分:find -maxdepth 1 -type d将返回当前工作目录中所有目录的列表。这通过管道传输到...

第二部分:while read -r dir; do开始while循环-只要进入while的管道是打开的(直到发送完整的目录列表),read命令就会将下一行放入变量“ dir”。然后继续...

第三部分:printf "%s:\t" "$dir";将在“ $ dir”(包含目录名称之一)中打印字符串,后跟制表符。

第四部分:find "$dir -f file"列出目录名称“ $ dir”中所有文件。此列表发送到。

第五部分:wc -l;计算发送到其标准输入中的行数。

最后一部分:done简单地结束while循环。

因此,我们获得了当前目录中所有目录的列表。对于每个目录,我们都会生成其中所有文件的列表,以便我们可以使用来对它们进行计数wc -l。结果将如下所示:

./dir1: 234
./dir2: 11
./dir3: 2199
...

始终将其read -r用作普通read对待反斜杠。然后echo -en "$dir:\t"将再次修改反斜杠;一个简单的解决方法是改为使用printf '%s:\t' "$dir"。接下来,$dir应该是"$dir"始终在变量替换周围使用双引号)。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

根据@Giles建议修改find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done
xenoterracide 2010年

2
我将sort -n -r -k2在结尾添加大量目录,以便我知道最常使用的位置
xenoterracide

第四部分:查找“ $ dir”,列出“ $ dir”中保存的目录名称内的所有文件。您忘记添加-type f使其成为列表文件:find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Krzysztof Boduch 2014年

@ krzysiek-boduch谢谢!我更新了答案。
Shawn J. Goff 2014年

15

试试看find . -type f | wc -l,它将计算当前目录中的所有文件以及子目录中的所有文件。请注意,所有目录都不会被视为文件,只有普通文件会被视为文件。


13

这是一些有用的清单命令的汇编(根据先前的用户代码重新哈希):

列出具有文件计数的文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

列出文件计数为非零的文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

列出具有子文件夹数量的文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

列出子文件夹数不为零的文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

列出空文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

列出具有内容计数的非空文件夹:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

顺便说一句..如果您想让这些列表命令中的任何一个按项目计数进行排序..将命令通过管道传递到一个排序中:“ a-list-command” | sort -n
DolphinDream

12

尝试:

find /path/to/start/at -type f -print | wc -l

作为起点,或者如果您真的只想遍历目录的子目录(并跳过该顶级目录中的文件)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l

为某事+1 | wc -l ...字数统计是一个很好的小工具
Johan

是的,但是它只包含一个目录...。我想获取目录中所有目录的计数,并且我不想每次都单独运行...当然,我想我可以使用一个循环...但是我很懒。
xenoterracide

find默认情况下,所有子目录都可递归工作。如果您希望它在多个位置工作,则可以在find和之间指定所有它们-type
Didier Trosset

那第二个肯定不起作用....我在/ home上尝试过。我知道了698035 。我应该看到大约6个数字。
xenoterracide

它对我有用-您确定下只有6个文件/home吗?我会百分百确定您不会。
Cry Havok,2010年

4

以下解决方案从当前目录开始计算已使用的inode的实际数量:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

要获取相同子集的文件数,请使用:

find . | wc -l

对于仅浏览子目录而不考虑当前目录中文件的解决方案,您可以参考其他答案。


1
考虑硬链接的好主意。假设GNU发现,你并不需要这么多的步骤:find -printf '%i\n' | sort -u | wc -l。如果要便携,则需要find . -exec ls -id {} + | cut …
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

2

OS X 10.6在接受的答案中阻塞了该命令,因为它未指定的路径find。而是使用:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

2

我知道我参加晚会很晚,但是我相信这种纯粹的bash(或接受双星球的其他外壳)解决方案在某些情况下可能会更快:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

输出:

d1/:    302
d2/:    24
d3/:    640
...

1

试试看:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

除非文件名包含换行符,否则它应该可以正常工作。


太递归了……我只想看顶层,它汇总了其下的所有内容。总计...这最终将打印每个目录。
xenoterracide 2010年

@xenoterracide:尝试-maxdepth 1在第一个之后立即添加find。如果要在计数中包括子目录的数量,请-type f在末尾删除。(! -type d无论如何应该如此,这样就可以包括所有非目录文件)。
丹尼斯·威廉姆森

1

如果已ncdu安装(要进行一些清理的必备工​​具),只需键入c“切换子项计数的显示”。并C“按项目排序”。


1
大声笑,这必须是最被接受的答案:)
x-yuri

0

du --inodes

我不确定为什么没有人(包括我自己)知道:

du --inodes
--inodes
      list inode usage information instead of block usage

我很确定这可以解决OP的问题。我已经开始大量使用它来找出我巨大的驱动器中所有垃圾的位置(​​并将其卸载到较旧的磁盘上)。

进一步的信息

如果您不想递归(在其他情况下可能会有用),请添加

-S, --separate-dirs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.