我想用循环来做for
。这是我到目前为止所想到的,但行不通。
for home in /home/ {.,/}*; do echo "$home"; done
如果可能的话,我想以非递归方式执行此操作。
答案1
with find
for 不是当前目录中的目录类型,无需递归:
find . ! -name . -prune ! -type d | grep -c /
...仅对目录删除第二个爆炸,或者对所有文件类型-type
完全删除测试。
在这种情况下这很容易,因为如果没有递归,我们只能看到每个文件一个路径分隔符,因此对于计数内容和计数位置不会产生混淆。当你应该计算文件数时计算换行符可能会导致麻烦 - 这两件事是不相关的。那么除此之外还能做什么呢?
find .//. | grep -c '^\.//\.'
...将返回子对象+以当前目录为根的该对象的准确计数。
同样有效,但逻辑相反,因为它在内部引用换行符并且可能更快,因为它只需要stat()
每个目录而不是每个组成文件:
\ls -1qRA . | grep -Exc \[^/]+
如果你放弃这个-R
选项,ls
它也可以在没有递归的情况下工作。
不过,根据文件名中的多字节字符和不兼容的区域设置,上述内容可能会返回错误计数。放入LC_ALL=C
符合 POSIX 标准ls
的环境中可以防止这种情况的发生,并且对于相当大的树的深度计数,这样做毕竟只能对性能有所帮助。
答案2
有许多更高级别的命令几乎可以完成您想做的事情,但这是如何在 shell 脚本中执行相同操作的一个很好的演示。这应该适用于任何系统具有/bin/sh
.它不依赖于任何其他命令。
您可以将此脚本保存为任何文件名,然后键入sh ./whatever_you_named_it
以执行它。
我把它分成两部分,列出文件, 和计算文件数。递归列出文件是最复杂的,但是一旦我们有了一个列表,就很容易对它们进行计数。
列出文件
该脚本递归地列出您的主目录或其作为参数接收的目录下的所有文件和目录。如果没有参数,则默认为主目录。
#!/bin/sh
if test $# -eq 0
then
startdir="$HOME"
else
startdir="$1"
fi
for f in "$start"/* # step through all files in the starting directory
do
echo "$f" # print the file name
if test -d "$f" # is the file a directory? (-d)
then
sh "$0" "$f" # yes call this script with the dir as arg
fi
done
让我们讨论一下每个步骤:
如果没有参数传递给脚本,则使用“$HOME”作为起始目录,否则使用第一个参数。 ($# 包含传递给该脚本的参数数量,我们使用 shell 的内置
test
命令来确定它是否为零):if test $# -eq 0 then startdir="$HOME" else startdir="$1" fi
迭代主目录中的文件。
"$HOME"/*
扩展到主目录顶层的所有非隐藏文件和目录:for f in "$HOME"/* do
打印文件名。我想你知道
echo
:echo "$f" # print the file name
使用选项调用 shell 内置
test
命令-d
。test
如果参数"$f"
是目录,则返回 true。这通常是[ -d "$f" ]
为了简洁而写的,但它确实是一个命令。 [在手册页中搜索“test expr”sh
]:if test -d "$f" # is the file a directory? (-d) then
下一个陈述是我们重复的地方。我们启动当前正在运行的脚本的新副本,并将当前的“$f”目录名称传递给它。扩展
$0
为当前 shell 脚本的文件名。我们不是在这里输入一些文件名,而是使用$0
这样的方式,即使名称发生更改,该脚本也能正常工作。例如,如果脚本被调用rlist
,那么您也可以编写sh rlist "$f"
,但如果脚本被重命名,脚本将不再正确运行,因为它将调用不存在的脚本,或者错误的脚本。 [参见手册页中的“特殊参数”sh
]:sh "$0" "$f" # yes call this script with the dir as arg
终止
if
语句和for
循环。fi done
计算文件数
到目前为止,该脚本列出了文件,但并未对它们进行计数。如果您想获取所有文件和目录的计数,请执行以下命令:
sh ./scriptname | wc -l
wc -l
是“字数统计”命令,并且使用该-l
选项仅计算行数。上面的管道打印一个数字,它是您的主目录下的文件数。
答案3
使用寻找:
当您说非递归时,您的意思是您只需要 /home 中的文件/目录计数,而不是任何子目录吗?如果是这种情况,您可以使用该选项将结果限制为顶级maxdepth
。
find /home -maxdepth 1 | wc -l
用于:
i=0; for home in ~/*; do (( i++ )); done; echo $i
请注意双括号和括起来的 i++ 之间的空格。