How to match a regex 1 to 3 times in a sed command?

Viewed 901

Problem

I want to get any text that consists of 1 to three digits followed by a % but without the % using sed.

What I tried

So i guess the following regex should match the right pattern : [0-9]{1,3}%.
Then i can use this sed command to catch the three digits and only print them :
sed -nE 's/.*([0-9]{1,3})%.*/\1/p'

Example

However when i run it, it shows :

$ echo "100%" | sed -nE 's/.*([0-9]{1,3})%.*/\1/p'
0

instead of

100

Obviously, there's something wrong with my sed command and i think the problem comes from here :

[0-9]{1,3}

which apparently doesn't do what i want it to do.

edit:

Solution

The .* at the start of sed -nE 's/.*([0-9]{1,3})%.*/\1/p' "ate" the two first digits.

The right way to write it, according to Wicktor's answer, is :

sed -nE 's/(.*[^0-9])?([0-9]{1,3})%.*/\2/p'
3 Answers

The .* grabs all digits leaving just the last of the three digits in 100%.

Use

sed -nE 's/(.*[^0-9])?([0-9]{1,3})%.*/\2/p'

Details

  • (.*[^0-9])? - (Group 1) an optional sequence of any 0 or more chars up to the non-digit char including it
  • ([0-9]{1,3}) - (Group 2) one to three digits
  • % - a % char
  • .* - the rest of the string.

The match is replaced with Group 2 contents, and that is the only value printed since n suppresses the default line output.

It will be easier to use a cut + grep option:

echo "abc 100%" | cut -d% -f1 | grep -oE '[0-9]{1,3}'
100

echo "100%" | cut -d% -f1 | grep -oE '[0-9]{1,3}'
100

Or else you may use this awk:

echo "100%" | awk 'match($0, /[0-9]{1,3}%/){print substr($0, RSTART, RLENGTH-1)}'
100

Or else if you have gnu grep then use -P (PCRE) option:

echo "abc 100%" | ggrep -oP '[0-9]{1,3}(?=%)'
100

This might work for you (GNU sed):

sed -En 's/.*\<([0-9]{1,3})%.*/\1/p' file

This is a filtering exercise, so use the -n option.

Use a back reference to capture 1 to 3 digits, followed by % and print the result if successful.

N.B. The \< ensures the digits start on a word boundary, \b could also be used. The -E option is employed to reduce the number of back slashes which would normally be necessary to quote (,),{ and } metacharacters.

Related