10

I can't seem to figure out how to write a regex correctly in an if statement. I wanted it to print out all the lines with "End Date" in it.

NUMBERS contains a text file with the following content:

End Date    ABC ABC ABC ABC ABC ABC
05/15/13    2   7   1   1   4   5  
04/16/13    4   3   0   1   3   6  
03/17/13    6   9   3   8   5   9  
02/18/13    8   2   7   1   0   1  
01/19/13    1   9   2   2   5   2  
12/20/12    7   2   7   1   0   1 

Here is a snippet of my code that I am having problems with:

if [ -f $NUMBERS ]
then
        while read line
        do
                if [ $line = ^End ]
                then
                        echo "$line"
                else
                        echo "BROKEN!"
                        break                   
                fi
        done < $NUMBERS
else
        echo "===== $NUMBERS failed to read  ====="
fi

The output is:

Broken!

3
  • You don't need regular expressions for something this simple: [[ $line == End* ]] Commented May 16, 2013 at 0:21
  • Does your file actually contain the > characters at the start of each line? Commented May 16, 2013 at 0:22
  • @glennjackman I was doing the regex for the ones with dates, but it wasn't working, so I did it for the first line to make sure nothing was going wrong. The actual file does not contain the ">". Commented May 16, 2013 at 2:07

3 Answers 3

14

if you're using bash, try =~:

...
if [[ $line =~ ^End ]]

Note that the following will NOT work:1

if [[ "$line" =~ "^End" ]]
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this is not portable to all shells.
@datguy What does "=~" do?
@dalawh =~ tells bash to match against a regex instead of a literal string.
4

The portable solution is to use case which supports wildcards (glob wildcards; not actual regular expressions) out if the box. The syntax is slightly freaky, but you get used to it.

while read -r line; do
    case $line in
        End*) ... your stuff here 
            ... more your stuff here
            ;;   # double semicolon closes branch
    esac
done

6 Comments

@cnst Indeed, this should be portable all the way back to the original Bourne sh. (No guarantees for csh, which some *BSD variants still - inexplicably - seem to cherish.)
Is it possible to use [0-9]* or equivalent? I want to check if the variable is 0 or positive integer.
Thanks for your suggestion @tripleee , in the meantime, I found [ -z "${inter##*[!0-9]*}" ] would also work, never think of ## in if statement!
The ## parameter expansion should be reasonably portable, i.e. it's in POSIX but might not be supported by legacy shells like Solaris sh. I really don't see how this discussion belongs here, though.
|
-1

You can use the following to check if the line begins with End

if [[ "$line" == End* ]]

You can use the following if you want to use regex.

if [[ "$line" =~ ^End* ]]

http://tldp.org/LDP/abs/html/comparison-ops.html

Also note that it is recommended to always quote your variables.

http://tldp.org/LDP/abs/html/quotingvar.html

6 Comments

I thought there was no difference between = and ==. Is there? Also, what is the difference from using one [] and two []?
if [ "$a" = "$b" ] -- does a string comparison, but == with [[ ]] can be used for regex searching. Pls look at the link I gave in the answer. Hope it helps. Copied from that link -- "The == comparison operator behaves differently within a double-brackets test than within single brackets."
can you show me your code, it should work...i have tested it.
@dalawh I had a small typo. I updated the answer. Pls use End* and see if that works.
[ is the basic old Bourne sh command test which does not support regex. The [[ variant is a Bash (and ksh etc) extension with improved robustness around corner cases as well as more capabilities, including =~ regex matching. The correct string equality operator is = though Bash leniently permits == as an alias.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.