3

Given:

$ shopt -s extglob
$ TEST="    z abcdefg";echo ">>${TEST#*( )z*( )}<<"
>> abcdefg<<

Why is there a space before the letter 'a'? I would expect that the 2nd *( ) would match the space, but it does not seams to do so.

I expected the equivalent of:

$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<"
>>abcdefg<<

The 2nd *( ) matches if I specify the next following character (which is 'a'):

$ shopt -s extglob
$ TEST="    z abcdefg";echo ">>${TEST#*( )z*( )a}<<"
>>bcdefg<<

Bash version: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

6

${TEST#...} matches the shortest string, which is z followed by zero spaces. You need ${TEST##...}, the longest match.

5

This is due to the interaction between the non-greedy substring removal and the type of pattern you're using.

From the bash manual,

?(pattern-list)

Matches zero or one occurrence of the given patterns.

*(pattern-list)

Matches zero or more occurrences of the given patterns.

+(pattern-list)

Matches one or more occurrences of the given patterns.

From my favorite explanation on bash string manipulation,

${string#substring}

Deletes shortest match of $substring from front of $string.

${string##substring}

Deletes longest match of $substring from front of $string.

So, when you specify ${TEST#*( )z*( )}, you're saying: "Please delete the shortest substring that has zero or more spaces, a z, then zero or more spaces.

Matching on the last space is longer than matching without it, so the last space is never matched.

To rectify this, you can either use ${TEST##*( )z*( )} to match the longest prefix ending with zero or more spaces or ${TEST#*( )z+( )} to match the shortest prefix ending with one or more spaces (which is functionally equivalent to matching the shortest prefix ending with one space).

1

As you want to mimic is a (perl) regex, then use a regex not a pattern:

$ test="    z abcdefg"
$ regex='^ *z *(.*)'
$ [[ $test =~ $regex ]]
$ echo ">>${BASH_REMATCH[1]}<<"
>>abcdefg<<

The regex is an extended regex, not a fully PCRE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.