Home > front end >  How to match a percentage regex in bash
How to match a percentage regex in bash

Time:01-12

I'm struggling checking if the my string is matching the percentage pattern, i.e. any non-space (or tab, new line) char repeat more than once, and at the end a percentage sign.

It should be easy, but I'm trying:

third_col="88.90%"
if [[ $third_col == '. %' ]]; then
  echo "matches"
fi

And it doesn't output "matches". I wonder what part in the regex was wrong.

CodePudding user response:

any non-space (or tab, new line) char repeat more than once, and at the end a percentage sign

Here is a non-regex way using extglob:

 ([![:blank:]])%

Which matches 1 or more of non-blank character followed by a %.

Code:

for s in '88.90%' '81.4' '5 1%' '' ' %' 'abc%'; do
    [[ $s ==  ([![:blank:]])% ]] && echo "'$s' ok" || echo "'$s' no"
done

'88.90%' ok
'81.4' no
'5 1%' no
'' no
' %' no
'abc%' ok

Thanks to comments below. If you are on bash version < 4.1 then enable extglob before running this script:

shopt -s extglob

CodePudding user response:

If you want to match any one or more non-whitespace chars and a % at the end, you need to use a regex (enabled with =~ operator), not a glob pattern (== uses glob pattern matching), and the pattern should be something like ^[^[:space:]] %$:

#!/bin/bash
third_col="88.90%"
rx='^[^[:space:]] %$'
if [[ "$third_col" =~ $rx ]]; then
  echo "matches"
fi

See the online demo. Here, [^[:space:]] matches one or more non-whitespace chars.

A bit more precise pattern will be

rx='^[0-9] (\.[0-9] )?%$'

See this online demo. Details:

  • ^ - start of string
  • [0-9] - one or more digits
  • (\.[0-9] )? - an optional sequence of a . and one or more digits
  • % - a % char
  • $ - end of string.

CodePudding user response:

A standard case statement can do that:

third_col=88.90%

case $third_col in
  *[[:space:]]*) ;;
  ?*%) echo matches ;;
esac

If there are any spaces in $third_col, do nothing. Otherwise, if it ends with "%", echo matches.

You can expand on the first pattern to reject other invalid cases, for example:

third_col=88.90%

case $third_col in
  *[!%.0123456789]* | *%*%* | *.*.*) ;;
  ?*%) echo matches ;;
esac
  •  Tags:  
  • Related