This question already has answers here:
How to match digits in regex in bash script
(2 answers)
Closed 6 years ago.
I'm trying to play with regular expressions in bash but i can't understand why this follow scenario doesn't work :
Regexp:
REGEXP="^(test\/)(([a-zA-Z]+)\-)+(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$"
String:
STRING="test/test-ods-1.10.1"
Test:
if [[ "$STRING" =~ $REGEXP ]]
then
echo "match!"
else
echo "don't match"
fi
Normally in this scenario I should receive a "match" but it's always returning a "doesn't match".
\d is not defined in bash regexps. Replace them with [0-9] and it'll work :
$ [[ "test/test-1.10.1" =~ ^(test\/)(([a-zA-Z]+)\-)+(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$ ]]; echo $?
1
$ [[ "test/test-1.10.1" =~ ^(test\/)(([a-zA-Z]+)\-)+(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; echo $?
0
No shorthand classes are defined in POSIX, and GNU extensions only bring a few of them, \w, \W, \s and \S according to regular-expressions.info.
Related
This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 4 years ago.
I have a Regex that I got to work in a sed search/replace line, but I can't get the Regex to work in an If-Then-Else.
This is my sed line:
YELLOW="\033[1;33m"
OUTPUT[0]="$YELLOW ==================================+==================================="
cLEN=${OUTPUT[0]}
cLEN="$(echo $cLEN | sed 's/\\[[:digit:]]\+\[[[:digit:]];[[:digit:]]\+m//g')"
However now I am trying to make an if condition and I can't get the syntax right. I need it to evaluate from the beginning of the line $cLEN
if [[ $cLEN =~ '^\\[[:digit:]]\+\[[[:digit:]];[[:digit:]]\+m\s' ]]; then
echo true
else
echo error
exit 1
fi
When the right-hand side of =~ is quoted, it's treated as a literal string to match, not a regex.
Store your regex in a variable, then leave the reference to that variable unquoted on the right-hand side of the expression.
re='^\\[[:digit:]]+\[[[:digit:]];[[:digit:]]+m'
[[ $cLEN =~ $re ]]; echo $?
This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 5 years ago.
In bash I have the following:
REGEX="(1.0.0|2.0.0)"
declare -a arr=("A:1.0.0" "B:1.0.0" "C:2.0.0" "D:2.0.1")
for i in "${arr[#]}"
do
echo "Found: $i"
if [[ "$i"=~"${REGEX}" ]]; then
echo "$i matches: ${REGEX}"
else
echo "$i DOES NOT match: ${REGEX}"
fi
done
I would assume that for D:2.0.1 it would print ...DOES NOT match... but instead it prints
Found: A:1.0.0
A:1.0.0 matches: (1.0.0|2.0.0)
Found: B:1.0.0
B:1.0.0 matches: (1.0.0|2.0.0)
Found: C:2.0.0
C:2.0.0 matches: (1.0.0|2.0.0)
Found: D:2.0.1
D:2.0.1 matches: (1.0.0|2.0.0)
So what is wrong with my REGEX group pattern? Specifying a group pattern like that works fine in other languages - e.g. like groovy.
You have a a typo in the regex match expression to start with
if [[ "$i"=~"${REGEX}" ]]; then
should have been written as just
if [[ $i =~ ${REGEX} ]]; then
which implicates the point that you should never quote your regex expressions. For it to understand the | operator in its extended regular expressions support(ERE) you need to make it understand that it is not a literal string which it treats so when under double-quotes.
Not recommended
But if you still want to quote your regex strings - bash 3.2 introduced a compatibility option compat31 (under New Features in Bash 1.l) which reverts bash regular expression quoting behavior back to 3.1 which supported quoting of the regex string. You just need to enable it via an extended shell option
shopt -s compat31
and run it with quotes now
if [[ $i =~ "${REGEX}" ]]; then
This question already has answers here:
How do I use regular expressions in bash scripts?
(2 answers)
Closed 8 years ago.
I'm trying to write a condition that would fit all the lines starting with a space/tab and the word Path
/sPath.* - simple regexp?
I found that in Bash 4.* it should look like:
if [[ $LINE =~ "[[:space:]]Path" ]]
But this condition for some reason does not work.
if [[ $LINE =~ [[:space:]] ]]
work fine, and displays all lines with spaces/tabs.
From version 3.2 onwards, the pattern (i.e., the regular expression) must not be quoted in Bash:
New Features in Bash
...
f. Quoting the string argument to the [[ command's =~ operator now
forces string matching, as with the other pattern-matching operators.
In other words, quoting is considered part of the regular expression itself (literal ").
Moreover, it would be better to quote the variable $LINE, to prevent errors should it be empty:
if [[ "$LINE" =~ [[:space:]] ]]
It is better to use:
[[ "$LINE" =~ [[:blank:]] ]]
Quote the variable LINE
Match with character class [[:blank:]] which is equivalent of space OR tab
This question already has answers here:
Why isn't this regular expression test working? [duplicate]
(3 answers)
Closed 9 years ago.
I need to ensure a variable passed to my shell script matches a certain pattern.
var x has to be in the form of AA-X.X.XX (ie AA-1.2.33). If it doesn't match I need to exit.
Any ideas?
Bash has direct support for regular expressions.
if ! [[ $mystring ~= $pattern ]]; then
exit
fi
Use Bash's Double-Bracket Regex Tests
See Conditional Constructs in the GNU Bash Manual for a complete explanation of the =~ binary operator. As an example:
good_string='AA-1.2.33'
bad_string='BB.11.222.333'
regex='^AA-[[:digit:]]\.[[:digit:]]\.[[:digit:]][[:digit:]]$'
[[ "$good_string" =~ $regex ]]
echo $? # 0
[[ "$bad_string" =~ $regex ]]
echo $? # 1
Doable directly in bash
var=AA-1.2.33
[[ $var =~ ^AA-.\..\...$ ]]
echo $?
0
var=AA-1.2.3355
[[ $var =~ ^AA-.\..\...$ ]]
echo $?
1
This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 9 years ago.
I have this
echo $line
Thisisaline.
I was wondering why is this not working:
if [[ "$line" =~ "[a-zA-Z]+\.$" ]] ; then echo "hello"; fi
Above regex gives no output.
The problem is that you are using quotes...
In bash regex, there is no need for quotes, and moreso, they should not be used (unless you are trying to match a quote (in which case you can escape it \")... Also if you want a space in your pattern, you must escape it, \ (there is a space after the back-slash ...
Also note, that to match the entire line as being alphabetic, you must add a leading ^ and a trailing $, otherwise it will match such lines as: 123 456 abc. cat and mouse
Try
if [[ $line =~ [a-zA-Z]+\. ]] ; then echo hello; fi
Some version of OS with bash gives you the output. So its up to you to get your updates.
However, without regex you can use extended globbing
shopt -s extglob
case "$line" in
+([a-zA-Z]). ) echo "hello";;
esac
if not, use regex without the quotes