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
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
I have the following bash script which should be producing the output TEST
#!/bin/bash
test="TEST:THING - OBJECT_X"
if [[ $test =~ ^([a-zA-Z0-9]+)\:([a-zA-Z0-9]+)[A-Z\s\-_]+$ ]]; then
echo ${BASH_REMATCH[1]}
fi
In my regex tester the regular expression seems to be matching and capturing on the first and second groups:
https://regex101.com/r/kR1jM7/1
Any idea whats causing this?
\s is a PCRE construct not meaningful inside of ERE. Use [:space:] instead. Also, instead of escaping the dash as \-, move the - to the very end of the character set definition.
The following works:
[[ $test =~ ^([a-zA-Z0-9]+):([a-zA-Z0-9]+)[A-Z[:space:]_-]+$ ]]
That said, for compatibility with a wider range of bash releases, move the regex into a variable:
re='^([a-zA-Z0-9]+):([a-zA-Z0-9]+)[A-Z[:space:]_-]+$'
[[ $test =~ $re ]]
To use POSIX character classes more aggressively (and thus make your code more likely to work correctly across languages and locales), also consider:
re='^([[:alnum:]]+):([[:alnum:]]+)[[:upper:][:space:]_-]+$'
This question already has answers here:
bash regex with quotes?
(5 answers)
Closed 3 years ago.
I'm having problem with bash regex match. I have regex like this:
re="fatal: file not found: .+/tmp_dir_1234/([^\ ]*) \(No such file or directory\)"
test="fatal: file not found: /some/path/irrelevant/something/tmp_dir_1234/somefile.txt (No such file or directory)"
if [[ "$test" =~ "$re" ]]; then
echo "match!"
fi
For me everything here looks good for now but for some reason while debugging bash script I can see that it doesn't match string here:
+ [[ fatal: file not found: /some/path/irrelevant/something/tmp_dir_1234/somefile.txt (No such file or directory) =~ fatal: file not found: \.\+/tmp_dir_1234/\(\[\^\\ ]\*\) \\\(No such file or directory\\\) ]]
For some reason regex pattern is escaped.
Remove the double quotes from the regular expression in the match:
if [[ "$test" =~ $re ]]; then
echo "match!"
fi
In double square brackets, there is no need to quote variables, as they are parsed in a special way. See man bash for details:
Word splitting and pathname expansion are not performed on the words between the [[ and ]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed.
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