我在这里找到了这个代码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*
(使用ls
with-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 中的模式不区分目录和文件,但是zsh
shell 可以*(.)
用来修改模式的行为以仅匹配常规文件(zsh
用户可能会在上面和下面的非变体中使用2009*(.)
而不是)。2009*
find
使用**
in (与shopt -s globstar
inbash
或set -o extended-glob
in yash
,或在可能支持它的任何其他 shell 中),以递归方式计数:
set -- **/2009*
echo "$#"
Run Code Online (Sandbox Code Playgroud)
该模式**
几乎匹配*
,但也匹配/
路径名。