非常简单的问题:假设我有一组文件:
a1.txt
a2.txt
a3.txt
b1.txt
我使用以下命令:
ls a*.txt
它将返回:
a1.txt a2.txt a3.txt
bash 脚本中有没有办法告诉使用 * 模式时将返回多少结果。在上面的例子中,如果我使用 a*.txt 答案应该是 3,如果我使用 *1.txt 答案应该是 2。
评论使用ls
:
ls
. 这是非常不可预测的,因为当您的文件名带有“不寻常的字符”(例如空格)时,这会中断。ls
依赖于实现。特定的实现可能会以不同的方式格式化输出。Greg Wooledge 维护的 bash wiki 上对解析 ls 输出的陷阱进行了很好的讨论 。
使用 bash 数组的解决方案
由于上述原因,使用 bash 语法将是更可靠的选择。您可以使用 glob 使用所有匹配的文件名填充 bash 数组。然后你可以询问 bash 数组的长度来获得匹配的数量。以下代码段应该可以工作。
files=(a*.txt) && echo "${#files[@]}"
要将匹配数保存在变量中,您可以执行以下操作:
files=(a*.txt)
count="${#files[@]}"
此方法的另一个优点是您现在还可以将匹配的文件放在一个可以迭代的数组中。
注意:虽然我一直在重复上面的bash 语法,但我相信上面的解决方案适用于所有sh -shell 系列。
您无法提前知道,但您可以计算返回了多少结果。IE
ls -l *.txt | wc -l
ls -l
将显示与指定通配符匹配的目录条目, wc -l 将为您提供计数。
您可以使用以下任一方法将此命令的值保存在 shell 变量中
num=$(ls * | wc -l)
或者
num=`ls -l *.txt | wc -l`
然后用于$num
访问它。第一种形式是首选。
您可以ls
结合使用wc
:
ls a*.txt | wc -l
该ls
命令每行列出一个匹配文件,并wc -l
计算行数。
我喜欢 suvayu 的回答,但没有必要使用数组:
count() { echo $#; }
count *
为了计算可能具有不可预知名称的文件,例如包含换行符、不可打印字符等,我将使用and with-print0
选项:find
awk
RS='\0'
num=$(find . -maxdepth 1 -print0 | awk -v RS='\0' 'END { print NR }')
调整选项以find
细化计数,例如,如果条件是当前目录中以小写开头并a
带有.txt
扩展名的文件,请使用:
find . -type f -name 'a*.txt' -maxdepth 1 -print0