我尝试计算目录内的文件数量,同时使用相同的脚本检查子目录并总结结果。
#!/bin/bash
var=0
var=$(ls -l $1 | grep "^-" | tr -s ' ' | cut -d ' ' -f 9 | wc -l)
for x in `ls -lr $1 | grep "^d" | tr -s ' ' | cut -d ' ' -f 9`;
do
output="$($0 $x)"
var=$((var+output))
done
echo $var
但是我没有得到正确的结果。
我究竟做错了什么?
答案1
$1
查找目录及其子目录中的常规文件总数:
find "$1" -type f -printf "1\n" | wc -l
要将该数字保存在变量中:
var=$(find "$1" -type f -printf "1\n" | wc -l)
即使文件或目录名称包含空格或其他困难字符,此方法也能起作用。
讨论
让我们考虑一下原始代码中的这一行:
for x in `ls -lr $1 | grep "^d" | tr -s ' ' | cut -d ' ' -f 9`;
首先,应该永不解析 ls。它不可靠。 的输出ls
会因版本而异。此外,由于特殊字符的处理方式, 显示的名称ls
不一定是文件或目录的正确名称。
其次,使用 shell 变量时,例如$1
,它们应该放在双引号中。否则,它们会被进行分词和路径名扩展,这会导致各种错误。
第三,形式如下:
for x in `...`
shell 将对命令替换的结果进行分词和路径名扩展。这也可能导致各种错误。
答案2
…我没有得到正确的结果。我做错了什么?
- 我不知道;你的脚本对我有用(在非常有限的测试中)。
- John1234 讨论了您的方法存在的问题。
我仍在尝试按照自己的方式做事
这是您的脚本的改编版,它(对我而言)有效并且使用更安全的机制:
#!/bin/bash
var=0
shopt -s nullglob
for x in "$1"/*
do
if [ -d "$x" ]
then
output="$($0 "$x")"
var=$((var+output))
else
var=$((var+1))
fi
done
echo $var
这与您的不同之处在于,我的将计算除目录之外的所有目录条目,而您的将不计算非纯文本文件(例如,符号链接、设备节点、命名管道、文件系统套接字等)
(shopt -s nullglob
用于处理没有内容的目录。)