rm/ls 与 [0-9] 的配合

rm/ls 与 [0-9] 的配合

我正在学习 shell 命令并遇到了短标签,例如[0-9]、[[:digit:]] 等。作为概念证明,我尝试使用 rm 命令删除所有文件(我知道它不是一个很好的做法,但我想了解事情是如何运作的),就像这样

rm [0-9].txt

目录中有两个文件 0.txt 和 9.txt ,它删除了文件 0.txt 和 9.txt 。我猜测表达式 [0-9] 被扩展然后读为 0.txt 1.txt 2 .txt ....但是,当您仅尝试 rm 5.txt 并且该文件不存在时,会引发错误。

有人请告诉我速记命令与 rm 或 ls 一起使用时如何工作。

答案1

这就是所谓的通配(链接到 bash 文档,但这并非特定于 bash)。

当您运行时rm [0-9].txt,shell 会扩展[0-9].txt到目录中与该模式匹配的文件列表。然后该列表作为参数传递给rm(每个文件作为单独的参数)。
所以不,shell 不会将其扩展为0.txt 1.txt ... 9.txt,它会查看匹配的文件。

为什么你只运行rm 5.txt,没有要扩展的 glob 模式,因此参数按原样传递给rm,它注意到该文件不存在并抱怨。

尝试其他方法:相同的命令rm [0-9].txt,但在一个目录中有与该模式匹配的任何文件。您会再次注意到rm抱怨,但这一次它会说:

rm: cannot remove '[0-9].txt': No such file or directory

如果 glob 模式不匹配任何内容,就会发生这种情况(无论如何默认情况下):shell 不会扩展它并保持不变。

此类模式匹配的 POSIX 参考:模式匹配表示法

答案2

不要用 测试rm,用 测试echo

[0-9].txt是通配符模式(也称为 glob)。它扩展为现有文件名的列表。在 glob 模式中,您可以使用三种通配符:

  • 该字符*匹配任何字符序列(包括空序列)。
  • 该字符?与任意一个字符匹配。
  • 括号表达式[…]匹配出现在括号内的任一字符。
    [0-9]是 的快捷方式[0123456789]。您可以-在括号内的两个字符之间使用 a 来表示这两个字符以及其间的任何两个字符。例如,[0-9a-z_]匹配数字、小写字母或下划线。
    还有一些关于括号的规则,我在这里不再提及。

重申一下,所有这些构造仅匹配现有文件。如果没有具有该名称的文件,[0-9].txt则不会扩展为,也不会扩展为如果没有具有该名称的文件,则不会扩展5.txt为更多。*.txtdfiojedfoi.txt

例子:

$ ls
0.txt  10.txt  1a.txt  9.txt  hello.txt  world.txt
$ echo [0-9].txt
0.txt 9.txt
$ echo [0-9][0-9].txt
10.txt
$ echo [0-9][0-9][0-9].txt
[0-9][0-9][0-9].txt
$ echo [0-9]?.txt
1a.txt 10.txt
$ echo [10-19].txt
0.txt 9.txt
$ echo *.txt
0.txt 1a.txt 9.txt 10.txt hello.txt world.txt
$ echo *l*
hello.txt world.txt

echo [0-9][0-9][0-9].txt只是重复该模式,因为没有匹配的文件。确保您理解为什么[10-19].txt只匹配这两个文件而不匹配10.txt19.txt

相关内容