0

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) ?

Sking
  • 3
  • 3

1 Answers1

1

!(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
oguz ismail
  • 1
  • 16
  • 47
  • 69
  • When `!(paris)` matches anything but `paris` shouldn't it discard the file which starts with `paris` & then give the result ?How come `paris` is still coming in the output ? – Sking Feb 16 '23 at 09:45
  • @Sking no, `!(paris)*` is no different from `*`. It'll match `paris_sept_2007_003.jpg` too because `!(paris)` matches `p`, `pa`, `par`, `pari`, `paris_`, etc. anything but `paris`, and `*` matches the rest. – oguz ismail Feb 16 '23 at 10:02
  • 1
    now I understand why above code do not work. Your above answer absolutely makes sense that `!(paris)*` is no different from `*`.Hence, even with `!(paris)*` as well because of last `*` it effectively matches all the file name present in that path. Thank you for your explanation. – Sking Feb 16 '23 at 10:58