How extglob negative matching works when expanding a parameter

Problem

Behavior

!(pattern-list)

does not work as I would expect when using a parameter in an extension, in particular

${parameter/pattern/string}

Enter

a="1 2 3 4 5 6 7 8 9 10"

Control cases

$ printf "%s\n" "${a/!([0-9])/}"
[blank]
#expected 12 3 4 5 6 7 8 9 10

$ printf "%s\n" "${a/!(2)/}"
[blank]
#expected  2 3 4 5 6 7 8 9 10

$ printf "%s\n" "${a/!(*2*)/}"
2 3 4 5 6 7 8 9 10
#Produces the behaviour expected in previous one, not sure why though

$ printf "%s\n" "${a/!(*2*)/,}"
,2 3 4 5 6 7 8 9 10
#Expected after previous worked

$ printf "%s\n" "${a//!(*2*)/}"
2
#Expected again previous worked

$ printf "%s\n" "${a//!(*2*)/,}"
,,2,
#Why are there 3 commas???

the functions

GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)

Notes

These are very simple examples, so if more complex examples with explanations can be included in the answer, please do so.

For more information or examples I need, let me know in the comments.

Have you already seen How extglob works with shell parameter extension? and even commented that the problem is with this particular problem, so please do not mark it as a hoax.

+6
source share
1 answer

${parameter/pattern/string} ( pattern /) parameter, pattern string. , $parameter prefix, match suffix ,

  • $parameter == "${prefix}${match}${suffix}"
  • $prefix - , (.. , , )
  • $match pattern
  • $prefix, $match / $suffix

${parameter/pattern/string} "${prefix}string${suffix}".

(${parameter//pattern/string}) suffix, ( ):

  • if "${prefix}${match}" != ""

    "${parameter//pattern/string}" = "${prefix}string${suffix//pattern/string}"
    

    else suffix=${parameter:1}

    "${parameter//pattern/string}" = "string${parameter:0:1}${suffix}//pattern/string}"
    

:

  • "${a/!([0-9])/}" --> prefix='' match='1 2 3 4 5 6 7 8 9 10' suffix=''. , "1 2 3 4 5 6 7 8 9 10" , , !([0-9]). , .

  • "${a/!(2)/}" --> prefix='' match='1 2 3 4 5 6 7 8 9 10' suffix=''. , "1 2 3 4 5 6 7 8 9 10" , "2" , , !(2). , .

  • "${a/!(*2*)/}" --> prefix='' match='1 ' suffix='2 3 4 5 6 7 8 9 10'. '1' *2* !(*2*).

  • "${a/!(*2*)/,}". , .

  • "${a//!(*2*)/}". , .

  • "${a//!(*2*)/,}" --> prefix='' match='1 ' suffix='2 3 4 5 6 7 8 9 10'. ${suffix//!(*2*)/,} ",2," . suffix !(*2*), . ( ), suffix , ' 3 4 5 6 7 8 9 10', !(*2*) .

+4

All Articles