有没有比 `find . | wc -l` 更快的方法来计算目录中的文件数量?

有没有比 `find . | wc -l` 更快的方法来计算目录中的文件数量?

我经常需要计算某个目录中文件的数量,有时候这个数字会达到数百万。

除了枚举和计数之外,还有更好的方法吗find . | wc -l? 是否有某种可以在 ext3/4 上进行 I/O 密集程度较低的文件系统调用?

答案1

虽然不是根本性的加速,但至少有一点:)

find . -printf \\n | wc -l

您实际上不需要传递文件名列表,只需传递换行符即可。当目录缓存在 RAM 中时,此变体在我的 Ubuntu 12.04.3 上的速度提高了约 15%。此外,此变体可以正确处理包含换行符的文件名。

有趣的是,这个变体似乎比上面的变体慢一点:

find . -printf x | wc -c

特殊情况 - 但速度非常快

如果目录位于其自己的文件系统上,您可以简单地计算 inode:

df -i .

如果除已计数的目录之外的其他目录中的目录和文件数量没有太大变化,您可以简单地从当前df -i结果中减去这个已知数字。这样,您将能够非常快速地计算文件和目录的数量。

答案2

我已经写了毛细管气管正是出于这个目的。它使用 ioctl 检索目录本身的物理偏移量fiemap,然后将目录遍历安排在多个连续的传递中以减少随机访问。与相比,您是否真正获得了加速取决于find | wc 以下几个因素:

  • 文件系统类型:支持 ioctl 的文件系统(如 ext4)fiemap将受益最多
  • 随机访问速度:HDD 的优势远大于 SSD
  • 目录布局:嵌套目录数量越多,优化潜力越大

当访问会导致元数据更新时,使用relatime或甚至重新安装也可能提高速度(对于所有方法)。nodiratime

答案3

实际上,在我的系统(Arch Linux)上,这个命令

   ls -A | wc -l

比以上所有方法都快:

   $ time find . | wc -l
  1893

   real    0m0.027s
   user    0m0.004s
   sys     0m0.004s
   $ time find . -printf \\n  | wc -l
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time find . -printf x  | wc -c
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time ls -A | wc -l
   1892

   real    0m0.007s
   user    0m0.000s
   sys     0m0.004s

答案4

改用fdfind. 这是并行遍历文件夹的快速替代方案

$时间查找〜-type f 2> / dev / null | wc -l
  445705
find ~ -type f 2> /dev/null 0.84s 用户 13.57s 系统 51% cpu总计 28.075
wc -l 0.03s 用户 0.02s 系统 0% cpu总计 28.074

$时间 fd -tf -sHI --显示错误。〜2> / dev / null | wc -l
  445705
fd -tf -sHI --show-errors . ~ 2> /dev/null 2.66s 用户 14.81s 系统 628% cpu总计 2.780
wc -l 0.05s 用户 0.05s 系统 3% cpu总计 2.779

find如您所见,要匹配中的选项,fd您需要-sHI --show-errors。默认情况下fd会跳过隐藏文件/文件夹,.gitignore并且也不会打印出权限错误,因此它甚至比这还要快得多。

可以通过仅打印新行而不是管道传输整个路径来进一步调整这一点。find您可以使用 来实现这一点-printf '\n'。目前不支持此功能fd,但这是请求的功能


请注意,在 Ubuntu 中,由于名称冲突,您需要使用fdfind而不是fd。您可以alias fd=fdfind克服较长的名称。显然,上述命令不适用于包含 的文件名\n。您需要像这样修复它

fd -t f -sHI . ~ | tr '\0\n' '\n\0' | wc -l

另一个好处是fd,当在交互式终端中运行它时,您还会获得漂亮的彩色文本,这与的输出不同find

相关内容