使用 [0-9] 处理 rm/ls

Wor*_*ine 4 ls shell wildcards

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

rm [0-9].txt
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*Mat 5

这称为globbing(链接到 bash 文档,但这并非特定于 bash)。

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

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

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

rm: cannot remove '[0-9].txt': No such file or directory
Run Code Online (Sandbox Code Playgroud)

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

这种模式匹配的 POSIX 参考:Pattern Matching Notation


Gil*_*il' 5

不要用rm测试,用echo

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

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

重申一下,所有这些结构都只匹配现有文件。如果没有具有该名称的文件,[0-9].txt则不会扩展到,5.txt如果没有具有该名称的文件,则*.txt不会扩展到dfiojedfoi.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
Run Code Online (Sandbox Code Playgroud)

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