Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I use the same regex with grep and it gives me a match but when doing it in a bash script, it return no match.

Test String(part of the file testregex.txt):

<a href="/os_x_lynx-wallpapers.html"><p>OS X Lynx</p><img src="/thumbs/os_x_lynx-t1.jpg"alt="OS X Lynx" class="thumb_img" width="270" height="169"/></a></div><div style="float:right;margin-right:13px;"></div></div>

This command correctly matches the highlighted part(and a few more):

grep -E '<img src="[^"]*\.jpg"' testregex.txt

But this bash script returns no match:

page=$(<testregex.txt)

if [[ $page =~ '<img src="[^"]*\.jpg"' ]]; then
    echo $1
    echo "match found"
else
    echo "match not found!"
fi
share|improve this question
    
Note: the regex also works without using the -E switch for grep –  udiboy1209 Apr 3 at 6:43

2 Answers 2

up vote 4 down vote accepted

In the case =~ operator, just don't use quotes for the right operator. This is considered an extended regular expression so in this case the single quotes will be part from he regular expression. So, using single quotes, a string like '<img src="/thumbs/os_x_lynx-t1.jpg"' (which contain also single quotes around it) will be found. See Meaning of “=~” operator in shell script.

Also, you must to escape any special character in your regex (quotes, spaces, shell redirection - <):

#!/bin/bash
page=$(<testregex.txt)

if [[ $page =~ \<img\ src=\"[^\"]*\.jpg\" ]]; then
    echo $1
    echo "match found"
else
    echo "match not found!"
fi

Apart of =~, you can use in your script your original command which uses grep:

#!/bin/bash

if grep -qE '<img src="[^"]*\.jpg"' testregex.txt ; then
    echo $1
    echo "match found"
else
    echo "match not found!"
fi

In this case I used -q option for grep to not write anything to standard output and to exit immediately if any match is found.

share|improve this answer
1  
There's also -q so you don't have to redirect to /dev/null and it will stop grepping once a match is found, or do the redirect and use -m 1 to achieve the same result. Depending on the size of the file, it might speed things up. –  mrjink Apr 3 at 9:40
1  
@mrjink You have perfectly right. I forgot about -q. I edited my answer. –  Radu Rădeanu Apr 3 at 9:47
    
Thanks for the update. I did end up using grep finally, because I wanted to perform actions on the matches and not just see if a match exists. –  udiboy1209 Apr 3 at 17:36

If you write [[ "$page" =~ '<img src="[^"]*\.jpg"' ]], then the right-hand side will be treated as an ordinary string, not a regex. See Bash regex statement. The solution is to escape all the special characters.

otherwise you can use regex statement in a separate variable within single quotes '' like,

var='<img src="[^"]*\.jpg'

in these case you do not need to escape special characters one by one.

#!/bin/bash
page=$(<testregex.txt)
var='<img src="[^"]*\.jpg'

if [[ "$page" =~ $var ]]; then
#    echo $1
    echo "match found"
else
    echo "match not found!"
fi

I have commented the echo $1 statement. Difference in single and double quotes in bash.

share|improve this answer
    
Wow that works! –  udiboy1209 Apr 3 at 6:59
    
Could you also show me how to put a backreference in there. Just adding brackets gives me a syntax error. Should be like this var=\<img src="([^"]*\.jpg) but that stray ) gives a syntax error. –  udiboy1209 Apr 3 at 7:02
    
OK I got it. Using single quotes when declaring var seems to work. –  udiboy1209 Apr 3 at 7:15
    
@udiboy look at the edit. I think your brackets issue is also solved. –  souravc Apr 3 at 8:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.