计算目录中具有特定名称的文件数

Jel*_*yse 4 ls wc

我在这里找到了这个代码https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html它很好地给了我目录中的文件数。

ls -1 | wc -l
Run Code Online (Sandbox Code Playgroud)

但我只想知道这些文件的名称中有多少以 2009 开头(例如20091210_005037.nc)。

我试过了,ls -1 | wc -l 2009*但它慢慢地列出了所有文件,似乎没有给我一个数字。

Kus*_*nda 10

set -- 2009*
echo "$#"
Run Code Online (Sandbox Code Playgroud)

这会将位置参数($1$2、 ... 等)的列表设置为匹配的名称2009*。这个列表的长度是$#.


问题ls -1 | wc -l 2009*在于您wc -l直接对匹配的文件执行2009*,计算每个文件的行数。同时,ls -1正在尝试写入 的标准输入wc,该输入wc没有读取,因为它获得了要处理的明确文件列表。

您可能想使用ls -d 2009* | wc -l. 这将列出所有匹配的名称2009*(使用lswith-d不列出目录的内容),并计算输出中的行数。请注意,-1如果您通过管道ls传输某处的结果(除非ls是强制列输出的别名或 shell 函数),则不需要。

另请注意,如果任何文件名包含换行符,这会给您错误的计数:

$ touch '2009
> was
> a
> good
> year'
$ ls
2009?was?a?good?year
$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 May 28 11:09 2009?was?a?good?year
$ ls -1
2009?was?a?good?year
$ ls | wc -l
       5
$ ls -1 | wc -l
       5
Run Code Online (Sandbox Code Playgroud)

然而:

$ set -- 2009*
$ echo "$#"
1
Run Code Online (Sandbox Code Playgroud)

(在大多数shell中使用set和输出$#额外不使用任何外部命令)


使用find递归数:

find . -type f -name '2009*' -exec echo . \; | wc -l
Run Code Online (Sandbox Code Playgroud)

在这里,我们为当前目录中或当前目录下的每个找到的路径名输出一个点,然后我们计算这产生的行数。我们不计算文件名字符串本身,而是这样做以避免在文件名包含换行符时计算太多行。

通过find我们能够更密切地控制我们计算的文件类型。以上,我们明确地测试规则的文件-type f(即不目录和其他类型的文件)。*shell 中的模式不区分目录和文件,但是zshshell 可以*(.)用来修改模式的行为以仅匹配常规文件(zsh用户可能会在上面和下面的非变体中使用2009*(.)而不是)。2009*find

使用**in (与shopt -s globstarinbashset -o extended-globin yash,或在可能支持它的任何其他 shell 中),以递归方式计数:

set -- **/2009*
echo "$#"
Run Code Online (Sandbox Code Playgroud)

该模式**几乎匹配*,但也匹配/路径名。