Search code examples
bashglobextglob

Negate in bash extended globs does not work


I am trying to list some selective files but want to exclude atop_20210428, but the following extended glob atop_20210@(3|4)*[0-4]*!(8)* does not exclude the file atop_20210428, what is the correction required in that?.

[root@server atop]# ls -lh atop_20210@(3|4)*[0-4]*!(8)*
-rw-r--r-- 1 root root 81M Mar 31 00:00 atop_20210330
-rw-r--r-- 1 root root 80M Apr  1 00:00 atop_20210331
-rw-r--r-- 1 root root 79M Apr  2 00:00 atop_20210401
-rw-r--r-- 1 root root 82M Apr  3 00:00 atop_20210402
-rw-r--r-- 1 root root 82M Apr  4 00:00 atop_20210403
-rw-r--r-- 1 root root 81M Apr  5 00:00 atop_20210404
-rw-r--r-- 1 root root 80M Apr  6 00:00 atop_20210405
-rw-r--r-- 1 root root 81M Apr  7 00:00 atop_20210406
-rw-r--r-- 1 root root 81M Apr  8 00:00 atop_20210407
-rw-r--r-- 1 root root 81M Apr  9 00:00 atop_20210408
-rw-r--r-- 1 root root 80M Apr 10 00:00 atop_20210409
-rw-r--r-- 1 root root 81M Apr 11 00:00 atop_20210410
-rw-r--r-- 1 root root 80M Apr 12 00:00 atop_20210411
-rw-r--r-- 1 root root 82M Apr 13 00:00 atop_20210412
-rw-r--r-- 1 root root 81M Apr 14 00:00 atop_20210413
-rw-r--r-- 1 root root 81M Apr 15 00:00 atop_20210414
-rw-r--r-- 1 root root 79M Apr 16 00:00 atop_20210415
-rw-r--r-- 1 root root 78M Apr 17 00:00 atop_20210416
-rw-r--r-- 1 root root 80M Apr 18 00:00 atop_20210417
-rw-r--r-- 1 root root 78M Apr 19 00:00 atop_20210418
-rw-r--r-- 1 root root 81M Apr 20 00:00 atop_20210419
-rw-r--r-- 1 root root 79M Apr 21 00:00 atop_20210420
-rw-r--r-- 1 root root 82M Apr 22 00:00 atop_20210421
-rw-r--r-- 1 root root 81M Apr 23 00:00 atop_20210422
-rw-r--r-- 1 root root 82M Apr 24 00:00 atop_20210423
-rw-r--r-- 1 root root 81M Apr 25 00:00 atop_20210424
-rw-r--r-- 1 root root 83M Apr 26 00:00 atop_20210425
-rw-r--r-- 1 root root 83M Apr 27 00:00 atop_20210426
-rw-r--r-- 1 root root 83M Apr 28 00:00 atop_20210427
-rw-r--r-- 1 root root 29M Apr 28 08:35 atop_20210428

I did turn on extglob already:

[root@server atop]# shopt -p extglob
shopt -s extglob
[root@server atop]#
[root@server atop]# shopt | grep extglob
extglob         on

Solution

  • * is matching everything, so *!(8)* is always going to match everything - first !(8) will not match anything (match empty), then * will match everything.

    atop_20210 @(3|4) * [0-4]  *  !(8)  *
    atop_20210    4       2             8
    

    Why all the *? Remove them. You want to just match what you want to match, not to match anything in between. Just:

    atop_20210@(3|4)[0-4]!(8)