假设我有两个文件/tmp
:
root@ubuntu:~# touch /tmp/hello.{pyc,py}
root@ubuntu:~# ls /tmp/
hello.py hello.pyc
现在,让我们rm -rf
使用 [co] 选项运行命令
root@ubuntu:~# rm -rf /tmp/hello.py[co]
root@ubuntu:~# ls /tmp/
hello.py
有人能解释一下这里发生了什么吗?[co]
参数是什么?我们如何才能让它适用于其他扩展?假设我有foo.js
和foo.coffee
文件,我们可以做些什么rm -rf /tmp/foo.coffe[co]
来删除/tmp/foo.js
?
答案1
[co]
不是rm
命令的参数——它是一个外壳全局与等于集合中单个字符的模式匹配[co]
- 换句话说,它匹配文件名末尾的ac
或a。来自:o
man bash
[...] Matches any one of the enclosed characters
为了匹配foo.coffee
和foo.js
,由于后缀根本不包含任何公共子字符串,所以最好的办法是foo.*
匹配任何文件名以开头foo.
你可以使用括号扩展例如
rm foo.{coffee,js}
答案2
它不是一个参数,而是一个字母集合(或“shell glob”)。这是一样的:
rm -rf /tmp/hello.py[co]
是相同的
rm -rf /tmp/hello.pyc
rm -rf /tmp/hello.pyo
相似的 ...
rm -rf /tmp/hello.py[c-o]
将删除从/tmp/hello.pyc
到/tmp/hello.pyo
ASCII 顺序的任何内容(包括以下内容)。
rm -rf /tmp/hello.py[ab][cd]
将删除...
rm -rf /tmp/hello.pyac
rm -rf /tmp/hello.pyad
rm -rf /tmp/hello.pybc
rm -rf /tmp/hello.pybd
比如说,我有 foo.js 和 foo.coffee 文件,我们可以做一些事情来
rm -rf /tmp/foo.coffe[co]
删除它们吗/tmp/foo.js
?
您可以采用相当奇特的方法,但对于这 2 个文件,我只会使用 1 个命令分别删除它们。另一个示例尽可能接近这 2 个文件...
rm /tmp/foo.[cj]*
将删除这样的文件...
rm /tmp/foo.c*
rm /tmp/foo.j*
因此它包含的内容远不止这两个文件。
答案3
它是一个 shell glob,类似于通配符*
和?
...在 bash 中,文件名模式匹配所有以或*.[co]
结尾的文件名。.c
.o
*.[co]
与*.c *.o
或的区别在于,如果目录中不存在文件,*.{c,o}
后两种模式将扩展为虚拟文件,而版本则不会。*.o
.o
*.[co]
Shell 全局变量对于以不区分大小写的方式执行文件操作非常有用。例如,如果您有一堆文件名以jpg
、JPG
、Jpg
、JPg
等结尾的文件...并且您想删除所有这些文件,您可以执行以下操作:
rm *.[Jj][Pp][Gg]