Bash extended glob pattern negation is not working in parameter substitution

98 Views Asked by At

Bash 3.2.57 (on macOS 12.6.8) extended glob pattern negation is not working in parameter substitution:

$ shopt -s extglob
$ s=abc
$ echo ${s##!(a)*}

I expected the last command to output abc, but it didn't output anything.

How can I make the third line output nothing if the first character of $s is not 'a', but output $s if the first character is 'a'?

2

There are 2 best solutions below

0
On

How can I make the third line output nothing if the first character of $s is not 'a', but output $s if the first character is 'a'?

case $s in a*) echo $s;; esac  # conditional execution

or

[[ $s =~ ^a ]] && echo $s      # conditional execution

or

[[ ${s:0:1} == a ]] && echo $s # conditional execution

or, more like what you tried,

echo ${s/#[^a]*/}              # string parsed to scrub nonmatch

Extended globbing not needed.

1
On

See

$ shopt -s extglob
$ [[ abc == a!(b)c ]] && echo yes || echo no
no
$ [[ ac == a!(b)c ]] && echo yes || echo no
yes

And from man bash:

  • !(pattern-list)

    Matches anything except one of the given patterns

So here the anything can be a null string. (I think Bash's manual could be more explicit about this.)