计算目录中文件数的最佳方法是什么?

rah*_*hmu 13 ls shell directory wildcards files

如果解析 的输出ls很危险,因为它可能会中断一些时髦的字符(空格、\n、 ... ),那么了解目录中文件数量的最佳方法是什么?

我通常依靠find避免这种解析,但同样地,find mydir | wc -l由于相同的原因会中断。

我现在正在 Solaris 上工作,但我正在寻找一个在不同的 unice 和不同的 shell 中尽可能可移植的答案。

roz*_*acz 19

这个技巧怎么样?

find . -maxdepth 1 -exec echo \; | wc -l
Run Code Online (Sandbox Code Playgroud)

作为便携式的findwc

  • 这不起作用(它在我的 Debian 系统上显示 `n+1` 个文件)。它也不过滤常规文件。 (5认同)
  • 我只是举了一个通用的例子。它确实有效,但*如何*它的工作方式取决于您如何根据您的特定需求调整 `find` 命令。是的,这个包含所有目录,包括`.`(这可能就是你看到结果为`n+1`的原因)。 (4认同)
  • 请注意,`-maxdepth` 不是标准的(GNU 扩展现在也被一些其他实现支持)。 (4认同)
  • @ChrisDown OP 没有指定对常规文件的过滤,而是要求提供目录中的文件数。要摆脱 n+1 问题,请使用 `find 。-最大深度1!-姓名 。-exec 回声 \; | wc -l`; 一些旧版本的 `find` 没有 `-not`。 (3认同)

enz*_*tib 12

使用 bash,没有外部实用程序,也没有循环:

shopt -s dotglob
files=(*)
echo ${#files[@]}
Run Code Online (Sandbox Code Playgroud)

在 ksh 中,替换shopt -s dotglobFIGNORE=.?(.). 在 zsh 中,将其替换为setopt glob_dots,或者删除shopt调用并使用files=(*(D)). (或者,如果您不想包含点文件,只需删除该行。)可移植,如果您不关心点文件:

set -- *
echo $#
Run Code Online (Sandbox Code Playgroud)

如果您确实想包含点文件:

set -- *
if [ -e "$1" ]; then c=$#; else c=0; fi
set .[!.]*
if [ -e "$1" ]; then c=$((c+$#)); fi
set ..?*
if [ -e "$1" ]; then c=$((c+$#)); fi
echo $c
Run Code Online (Sandbox Code Playgroud)

  • 第一个示例在未启用 `nullglob` 时为空目录打印 `1`。在 zsh 中,带有 `N` (`nullglob`) 限定符的 `a=(*(DN));echo ${#a}` 不会导致空目录错误。 (3认同)

Sté*_*las 8

find . ! -name . -prune -print | grep -c /
Run Code Online (Sandbox Code Playgroud)

对 80 后系统应该相当便携。

这会计算当前目录中除...中的所有目录条目。

还要计算子目录中的文件:

find .//. ! -name . | grep -c //
Run Code Online (Sandbox Code Playgroud)

(那个甚至应该可以移植到 Unix V6(1975),因为它不需要-prune

  • `找到目录名!如果其中还有其他名为“dirname”的目录,则 -name dirname 不起作用。最好使用“find dirname/”。!-名字.`. `wc -l` 计算行数,文件名可以由多行组成,因为换行符与文件名中的任何字符一样有效。 (2认同)

Arc*_*ege 7

尝试:

ls -b1A | wc -l
Run Code Online (Sandbox Code Playgroud)

-b将非打印字符,-A将显示除所有文件...每行(在管道上的默认,但好是明确的)一个。

只要我们包括更高级的脚本语言,这里是 Python 中的单行代码:

python -c 'import os; print len(os.listdir(os.sep))'
Run Code Online (Sandbox Code Playgroud)

或者使用完整的“查找”:

python -c 'import os; print len([j for i in os.walk(os.sep) for j in i[1]+i[2]])'
Run Code Online (Sandbox Code Playgroud)