bash如何在extglob中内部实现反模式匹配?

huangapple go评论60阅读模式
英文:

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 &quot;paris&quot; 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

huangapple
  • 本文由 发表于 2023年2月16日 17:19:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定