2

非常简单的问题:假设我有一组文件:

a1.txt
a2.txt
a3.txt
b1.txt

我使用以下命令:

ls a*.txt

它将返回:

a1.txt a2.txt a3.txt

bash 脚本中有没有办法告诉使用 * 模式时将返回多少结果。在上面的例子中,如果我使用 a*.txt 答案应该是 3,如果我使用 *1.txt 答案应该是 2。

4

5 回答 5

5

评论使用ls

  1. 我看到所有其他答案都通过解析 ls. 这是非常不可预测的,因为当您的文件名带有“不寻常的字符”(例如空格)时,这会中断。
  2. 另一个陷阱是,它ls依赖于实现。特定的实现可能会以不同的方式格式化输出。

Greg Wooledge 维护的 bash wiki 上对解析 ls 输出的陷阱进行了很好的讨论 。

使用 bash 数组的解决方案

由于上述原因,使用 bash 语法将是更可靠的选择。您可以使用 glob 使用所有匹配的文件名填充 bash 数组。然后你可以询问 bash 数组的长度来获得匹配的数量。以下代码段应该可以工作。

files=(a*.txt) && echo "${#files[@]}"

要将匹配数保存在变量中,您可以执行以下操作:

files=(a*.txt)
count="${#files[@]}"

此方法的另一个优点是您现在还可以将匹配的文件放在一个可以迭代的数组中。

注意:虽然我一直在重复上面的bash 语法,但我相信上面的解决方案适用于所有sh -shell 系列。

于 2012-07-22T23:33:26.090 回答
4

您无法提前知道,但您可以计算返回了多少结果。IE

  ls -l *.txt | wc -l

ls -l将显示与指定通配符匹配的目录条目, wc -l 将为您提供计数。

您可以使用以下任一方法将此命令的值保存在 shell 变量中

  num=$(ls * | wc -l)

或者

  num=`ls -l *.txt | wc -l`

然后用于$num访问它。第一种形式是首选。

于 2012-07-22T22:35:33.307 回答
3

您可以ls结合使用wc

ls a*.txt | wc -l

ls命令每行列出一个匹配文件,并wc -l计算行数。

于 2012-07-22T22:35:14.057 回答
2

我喜欢 suvayu 的回答,但没有必要使用数组:

count() { echo $#; }
count *
于 2012-07-24T21:13:08.217 回答
1

为了计算可能具有不可预知名称的文件,例如包含换行符、不可打印字符等,我将使用and with-print0选项:findawkRS='\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
于 2012-07-23T00:09:03.123 回答