我正在寻找一个对当前目录(不包括子目录)中的文件进行计数的脚本。它应该遍历每个文件,如果不是目录,则增加计数。输出应该只是一个表示文件数量的整数。
我想出了
find . -type f | wc -l
但我真的不认为它能完成整个计数工作。这是一项作业,因此如果您只想为我指明正确的方向,那就太好了。
答案1
如果您只想要常规文件,
使用 GNU find
:
find . -maxdepth 1 -type f -printf . | wc -c
其他find
的:
find . ! -name . -prune -type f -print | grep -c /
(你不希望-print | wc -l
这样,因为如果文件名带有换行符,那么这将不起作用)。
和zsh
:
files=(*(ND.)); echo $#files
和ls
:
ls -Anq | grep -c '^-'
要包含常规文件的符号链接,请更改-type f
为-xtype f
with GNU find
、或-exec test -f {} \;
with other find
、或.
with -.
with zsh
,或将-L
选项添加到ls
。但请注意,您可能会得到假阴性在无法确定符号链接目标类型的情况下(例如,因为它位于您无权访问的目录中)。
如果您想要任何类型的文件(符号链接、目录、管道、设备...),而不仅仅是常规文件:
find . ! -name . -prune -printf . | wc -c
(更改为-print | grep -c /
with non-GNU find
、(ND.)
with (ND)
、zsh
with grep -c '^-'
with wc -l
)ls
。
然而,这不算数.
或..
(通常,人们并不真正关心它们,因为它们总是存在),除非您-A
用-a
替换ls
。
如果您想要除目录之外的所有类型的文件,请替换-type f
为! -type d
(或! -xtype d
同时排除目录的符号链接),并zsh
替换.
为^/
,替换为ls
,替换grep -c '^-'
为grep -vc '^d'
。
如果要排除隐藏文件,请添加! -name '.*'
或zsh
,删除D
或ls
,删除A
.
答案2
排除子目录
find . -maxdepth 1 -type f | wc -l
这假设所有文件名都不包含换行符,并且您的 find 实现支持该-maxdepth
选项。
答案3
到迭代在当前目录中的所有内容上,使用
for f in ./*; do
然后使用
[ -f "$f" ]
或者
test -f "$f"
测试你得到的东西是否是一个常规文件(或一个符号链接)。
请注意,这将排除套接字文件或其他特殊文件。
到只排除目录, 使用
[ ! -d "$f" ]
反而。
变量的引用很重要,否则如果存在一个名为 的目录hello world
和一个名为 的文件,则会错误计数hello
。
还要匹配隐.
文件(文件名中带有前导的文件),可以使用(in ) 设置dotglob
shell 选项,或者使用shopt -s dotglob
bash
for f in ./* ./.*; do
如果您希望 shell 在这些 glob 模式不匹配任何内容时不返回任何内容(否则您将得到文字字符串和/或in ),那么设置nullglob
shell 选项 (in )也可能是明智的。bash
./*
./.*
f
注意:我避免提供完整的脚本,因为这是一项作业。
答案4
如果您想要处理包含嵌入换行符和其他不可打印字符的文件的东西,那么此解决方案将起作用。但这对于你的任务来说几乎肯定是多余的。
find . -maxdepth 1 -type f -print0 | tr -dc '\0' | wc -c
这样做的作用是丢弃除\0
每个文件名末尾的尾随之外的所有内容。然后它会计算这些字符,从而得出文件的数量。