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)

3 Answers 3

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

0
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .