How can bash recognize regex groups? [duplicate] - regex

This question already has answers here:
Capturing Groups From a Grep RegEx
(10 answers)
Closed 2 years ago.
I am trying to use regex to match a filename out of a path.
#!/bin/bash
regex=[^/]+?(?=.zip)
path="/home/quid/Downloads/file.zip"
if [[ $path =~ $regex ]]
then
echo "Found a match"
echo $BASH_REMATCH
fi
I should get
Found a match
file
Instead bash gives me this error
another.sh: line 2: syntax error near unexpected token `('
another.sh: line 2: `reg=[^/]+?(?=.zip)'
If I put the regex in a quotes, it no longer is recognized as regex. I have zsh 5.8 and bash 5.0.16 and it doesn't work on both shells.
How can I get bash to recognize the regex or not give me an error for using regex groups?

#!/bin/bash
regex='([^/.]+)([.]zip)?$'
path="/home/quid/Downloads/file.zip"
if [[ $path =~ $regex ]]
then
echo "Found a match"
echo "${BASH_REMATCH[1]}"
fi
Using Charles' regex and ${BASH_REMATCH[1]} gives me just the file name without the extension.

Related

BASH Pattern in IF-Then_Else [duplicate]

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 $?

Matching groups in bash regex [duplicate]

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

Regular expression does not match, no idea why

I moved my server to a new one (cheaper). Both have the same Linux (CentOS) in different versions (5.0 and 6.5). I have a shell script that filters a line out of a log:
if [ -f $URLFILE ]
then
echo "File found, getting userinfo..."
while read line;
do
if [[ $line =~ ".Userlist: .*" ]]
then
echo "Found user information."
echo $line > /home/....net.txt;
...
So, if the red line matches the regex, it should be echoed into the file. This works fine on the old system but the regex does not match on the new system (without any other changes). The regex is correct as far as a regex tester on the Internet tells me.
There are 2 problems:
sh doesn't support regex matching using =~ like bash
Regex should NOT be quoted and your variable should preferably be quoted.
You can use this in BASH:
if [[ "$line" =~ Userlist:[[:blank:]] ]]
OR just avoid using regex altogether and use glob matching:
if [[ "$line" == *"Userlist: "* ]]

Bash regex match not working - escaping all special characters [duplicate]

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.

Why isn't this regular expression test working? [duplicate]

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