是否有一个bash命令来计算匹配模式的文件数量?

例如,我想获取目录中所有文件的计数,这些文件都符合这个模式:log*


当前回答

我已经对这个答案进行了很多思考,特别是考虑到不要解析这些东西。起初,我尝试过

<WARNING! DID NOT WORK>
du --inodes --files0-from=<(find . -maxdepth 1 -type f -print0) | awk '{sum+=int($1)}END{print sum}'
</WARNING! DID NOT WORK>

如果只有像这样的文件名,这是可行的

touch $'w\nlf.aa'

但如果我创建这样的文件名就失败了

touch $'firstline\n3 and some other\n1\n2\texciting\n86stuff.jpg'

我终于想到了下面这些。注意,我试图获得目录中所有文件的计数(不包括任何子目录)。我认为它,连同@Mat和@Dan_Yard的答案,以及至少有@mogsie设定的大部分要求(我不确定内存)。我认为@mogsie的答案是正确的,但我总是尽量避免解析ls,除非是非常特定的情况。

awk -F"\0" '{print NF-1}' < <(find . -maxdepth 1 -type f -print0) | awk '{sum+=$1}END{print sum}'

更可读的:

awk -F"\0" '{print NF-1}' < \
  <(find . -maxdepth 1 -type f -print0) | \
    awk '{sum+=$1}END{print sum}'

这是专门为文件执行查找,用空字符分隔输出(以避免空格和换行问题),然后计算空字符的数量。文件的数量将比空字符的数量少一个,因为在最后会有一个空字符。

要回答OP的问题,有两种情况需要考虑

1)非递归搜索:

awk -F"\0" '{print NF-1}' < \
  <(find . -maxdepth 1 -type f -name "log*" -print0) | \
    awk '{sum+=$1}END{print sum}'

2)递归搜索。请注意,name参数中的内容可能需要针对略有不同的行为(隐藏文件等)进行更改。

awk -F"\0" '{print NF-1}' < \
  <(find . -type f -name "log*" -print0) | \
    awk '{sum+=$1}END{print sum}'

如果有人想评论这些答案与我在这个答案中提到的答案相比如何,请评论。


注意,我是在得到这个答案的同时进行这个思考过程的。

其他回答

ls -1 log* | wc -l

这意味着每行列出一个文件,然后将其输送到单词计数命令,参数切换到计数行。

要计算所有内容,只需将ls管道到单词计数行:

ls | wc -l

要使用模式计数,首先将管道连接到grep:

ls | grep log | wc -l

这是我的一句话。

 file_count=$( shopt -s nullglob ; set -- $directory_to_search_inside/* ; echo $#)

下面是一个可以在脚本中使用的通用Bash函数。

    # @see https://stackoverflow.com/a/11307382/430062
    function countFiles {
        shopt -s nullglob
        logfiles=($1)
        echo ${#logfiles[@]}
    }

    FILES_COUNT=$(countFiles "$file-*")

你可以用bash安全地做到这一点(即不会被名称中有空格或\n的文件所bug):

$ shopt -s nullglob
$ logfiles=(*.log)
$ echo ${#logfiles[@]}

您需要启用nullglob,以便在没有匹配的文件时不会在$logfiles数组中获得*.log文本。(参见如何“撤消”一个“set -x”?有关如何安全重置的示例。)