除了基本的 *
、 ?
和 [...]
模式之外,Bash shell 还提供了扩展的模式匹配运算符,如 !(pattern-list)
(“匹配除给定模式之一之外的所有模式”)。需要设置 extglob
shell 选项才能使用它们。一个例子:
~$ mkdir test ; cd test ; touch file1 file2 file3
~/test$ echo *
file1 file2 file3
~/test$ shopt -s extglob # make sure extglob is set
~/test$ echo !(file2)
file1 file3
如果我将 shell 表达式传递给在子 shell 中执行它的程序,则操作符会导致错误。这是一个直接运行子 shell 的测试(这里我从另一个目录执行以确保扩展不会过早发生):
~/test$ cd ..
~$ bash -c "cd test ; echo *"
file1 file2 file3
~$ bash -c "cd test ; echo !(file2)" # expected output: file1 file3
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
我尝试了各种转义,但我想出的任何方法都无法正常工作。我还怀疑
extglob
没有设置在子 shell 中,但事实并非如此:~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
任何解决方案表示赞赏!
最佳答案
$ bash -O extglob -c 'echo !(file2)'
文件 1 文件 3