查找目录中的文件数

时间:2010-09-13 15:55:35

标签: linux file shell directory counting

Linux中是否有任何方法可以计算O(1)中目录(即直接子节点)中的文件数(与文件数无关),而无需先列出目录?如果不是O(1),是否有合理有效的方法?

我正在寻找ls | wc -l的替代方案。

8 个答案:

答案 0 :(得分:37)

readdir并不像你想象的那么昂贵。诀窍是避免统计每个文件,并(可选)对ls的输出进行排序。

/bin/ls -1U | wc -l

避免shell中的别名,不对输出进行排序,并列出每行1个文件(在将输出汇总到wc时不是绝对必要的。)

原始问题可以改为“目录的数据结构是否存储了条目数的计数?”,答案是否定的。没有比readdir(2)/ getdents(2)更有效的文件计数方法。

答案 1 :(得分:11)

通过stat'ing(stat(1)或stat(2))给定目录并观察到该目录的链接数,可以获得给定目录的子目录数而不遍历整个列表。具有N个子目录的给定目录将具有N + 2的链接计数,每个子目录的“...”条目的一个链接,以及“。”的两个链接。和给定目录的“..”条目。

然而,如果没有遍历整个列表,就无法获得所有文件的数量(无论是常规文件还是子目录) - 这是正确的。

然而,“/ bin / ls -1U”命令不会获得所有条目。它将仅 那些不以点(。)字符开头的目录条目。例如,它不会计算许多登录$ HOME目录中的“.profile”文件。

可以使用“/ bin / ls -f”命令或“/ bin / ls -Ua”命令来避免排序并获取所有条目。

或许不幸的是,“/ bin / ls -f”命令或“/ bin / ls -Ua”命令也会计算“。”。和每个目录中的“..”条目。您必须从计数中减去2以避免计算这两个条目,例如以下内容:

expr `/bin/ls -f | wc -l` - 2     # Those are back ticks, not single quotes.

在管道“ls”输出时,“/ bin / ls -Ua”命令中不需要--format = single-column(-1)选项,在本例中为“wc”。如果输出不是终端,“ls”命令将自动将其输出写入单个列。

答案 2 :(得分:3)

-U的{​​{1}}选项不在POSIX中,而在OS X的ls中,它与GNU ls具有不同的含义,即ls -t 1}}和-l使用创建时间而不是修改时间。 -f在POSIX中作为XSI扩展。 GNU手册ls-f描述为do not sort, enable -aU, disable -ls --color,将-U描述为do not sort; list entries in directory order

POSIX描述-f是这样的:

  

强制将每个参数解释为目录,并列出每个插槽中找到的名称。此选项应关闭-l-t-s-r,并打开-a;顺序是条目在目录中出现的顺序。

ls|wc -l之类的命令会在文件名包含换行符时给出错误的结果。

在zsh中你可以这样做:

a=(*(DN));echo ${#a}

Dglob_dots)包含名称以句点开头且Nnull_glob)的文件导致该命令不会导致空目录中的错误。

或者在bash中也一样:

shopt -s dotglob nullglob;a=(*);echo ${#a[@]}

如果IFS包含ASCII数字,请在${#a[@]}周围添加双引号。添加shopt -u failglob以确保failglob未设置。

便携式选项是使用find

find . ! -name . -prune|grep -c /
如果文件名不包含换行符,则

grep -c /可以替换为wc -l! -name . -prune-mindepth 1 -maxdepth 1的便携替代品。

或者这是另一种通常不包含名称以句点开头的文件的替代方案:

set -- *;[ -e "$1" ]&&echo "$#"

但是,上面的命令包含的名称以bash中的dotglob或zsh中的glob_dots之类的选项开头的句点。当*未匹配任何文件时,该命令会在zsh中使用默认设置导致错误。

答案 3 :(得分:2)

我使用了这个命令..像魅力一样......只能更改maxdepth ..这是子目录

find * -maxdepth 0 -type d -exec sh -c "echo -n {} ' ' ; ls -lR {} | wc -l" \;

答案 4 :(得分:2)

我认为您可以使用final Thread endChecker = new Thread(() -> { while(true){ try{ Thread.sleep(100); if(!frame.isDisplayable() && !thread.isAlive()) System.exit(0); }catch(InterruptedException ex){ break; } } }); endChecker.start(); 对此进行更多控制:

find
  • find <path> -maxdepth 1 -type f -printf "." | wc -c 不会深入到文件层次结构中。
  • find -maxdepth 1允许过滤到文件。同样,您可以将-type f用于目录。
  • -type d为每场比赛打印一个点。
  • -printf "."对字符进行计数,因此它会计算wc -c ...创建的点数,这意味着计算给定路径中存在的文件数量。

答案 5 :(得分:1)

据我所知,没有更好的选择。这个信息可能与这个问题有关,你可能已经知道在Linux下(一般在Unix下)目录只是包含其他文件列表的特殊文件(我知道具体细节将取决于特定文件)系统,但这是一般的想法)。并且没有调用来查找没有遍历整个列表的条目总数。如果我错了,请让我纠正。

答案 6 :(得分:0)

有关当前目录中所有文件的编号,请尝试以下操作:

<input matInput placeholder="Name" [(ngModel)]="profile.name">

答案 7 :(得分:-1)

使用ls -1 | wc -l <​​/ p>