英文:
How bash inverse pattern matching works internally in extglob?
问题
当前目录中存在以下文件。
```plaintext
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_july_2001_001.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_march_2004_002.png
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 newyork_dec_2012_005.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 paris_sept_2007_003.jpg
我想过滤掉除以"paris"开头的所有图像。
我尝试了下面的命令,符合我的期望。
ls -l !(paris*)
但是,我不明白为什么以下两个命令不能给我预期的输出。在这两种情况下,它都显示了所有4个文件。
ls -l !(paris)*.*(jpeg|jpg|png)
ls -l !(paris)*
Bash如何在内部解释这种扩展的通配符语法?它首先尝试匹配!(paris),然后尝试匹配(jpeg|jpg|png)吗?
<details>
<summary>英文:</summary>
Below files are present in current directory.
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_july_2001_001.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 london_march_2004_002.png
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 newyork_dec_2012_005.jpeg
-rw-r--r-- 1 kazama kazama 0 Feb 16 08:50 paris_sept_2007_003.jpg
I want to filter all images except which starts with "paris" text.
I have tried below command which works as per my expectation.
ls -l !(paris*)
But, I do not understand why below 2 commands do not give me expected output. In both of the cases it shows all the 4 files.
`ls -l !(paris)*.*(jpeg|jpg|png)`
`ls -l !(paris)*`
How bash interprets this extended globbing syntax internally ?Is it first trying to match !(paris) then it tries to match (jpeg|jpg|png) ?
</details>
# 答案1
**得分**: 1
`!(paris)` 匹配除了 `paris` 之外的任何内容,包括 `paris_`, `pari`, `par`, `pa`, `p`,甚至是空字符串。Bash 会找到与 `paris` 不匹配的部分,然后尝试将路径名的其余部分与模式的其余部分匹配。请参考以下示例:
``` none
$ echo !(paris)london*
london_july_2001_001.jpeg london_march_2004_002.png
$ echo !(paris)_*
london_july_2001_001.jpeg london_march_2004_002.png newyork_dec_2012_005.jpeg paris_sept_2007_003.jpg
$ echo !(paris)_*_*_*
london_july_2001_001.jpeg london_march_2004_002.png newyork_dec_2012_005.jpeg
英文:
!(paris)
matches anything but paris
, which includes paris_
, pari
, par
, pa
, p
, and even the empty string. Bash will find something that doesn't match paris
and try to match the rest of the pathname against the rest of the pattern. See:
$ echo !(paris)london*
london_july_2001_001.jpeg london_march_2004_002.png
$ echo !(paris)_*
london_july_2001_001.jpeg london_march_2004_002.png newyork_dec_2012_005.jpeg paris_sept_2007_003.jpg
$ echo !(paris)_*_*_*
london_july_2001_001.jpeg london_march_2004_002.png newyork_dec_2012_005.jpeg
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论