Atomiklan
Atomiklan

Reputation: 5454

Bash while loop if statment

Can anyone see whats wrong here? If I put X|9 in lan.db (or any db in this directory) and run the following code, the IF statement does not work. It's weird! if you echo $LINE, it is indeed pulling X|9 out of lan.db (or any db in this directory) and setting it equal to LINE, but it wont do the comparison.

DBREGEX="^[0-9]|[0-9]$"
shopt -s nullglob
DBARRAY=(databases/*)
i=0
for i in "${!DBARRAY[@]}"; do 
    cat ${DBARRAY[$i]} | grep -v \# | while read LINE; do
        echo "$LINE" (Whats weird is that LINE DOES contain X|9)
        if [[ !( $LINE =~ $DBREGEX ) ]]; then echo "FAIL"; fi
    done
done

If however I just manually sent LINE="X|9" the same code (minus the while) works fine. ie LINE=X|9 fails, but LINE=9|9 succeeds.

DBREGEX="^[0-9]|[0-9]$"
Comment shopt -s nullglob
Comment DBARRAY=(databases/*)
Comment i=0
Comment for i in "${!DBARRAY[@]}"; do 
Comment     cat ${DBARRAY[$i]} | grep -v \# | while read LINE; do
                LINE="X|9"
                if [[ !( $LINE =~ $DBREGEX ) ]]; then echo "FAIL"; fi
Comment     done
Comment done

* UPDATE *

UGH I GIVE UP

Now not even this is working...

DBREGEX="^[0-9]|[0-9]$"
LINE="X|9"
if [[ ! $LINE =~ $DBREGEX ]]; then echo "FAIL"; fi

* UPDATE *

Ok, so it looks like I have to escape |

DBREGEX="^[0-9]\|[0-9]$"
LINE="9|9"
echo "$LINE"
if [[ ! $LINE =~ $DBREGEX ]]; then echo "FAIL"; fi

This seems to work ok again

Upvotes: 0

Views: 165

Answers (2)

choroba
choroba

Reputation: 242218

| has a special meaning in a regular expression. ^[0-9]|[0-9]$ means "starts with a digit, or ends with a digit". If you want to match a literal vertical bar, backslash it:

DBREGEX='^[0-9]\|[0-9]$'
for LINE in 'X|9' '9|9' ; do
    echo "$LINE"
    if [[ ! $LINE =~ $DBREGEX ]] ; then echo "FAIL" ; fi
done

Upvotes: 1

anubhava
anubhava

Reputation: 786031

You don't need round brackets in regex evaluation. You script is also creating a sub shell and making a useless use of cat which can be avoided.

Try this script instead:

while read LINE; do
    echo "$LINE"
    [[ "$LINE" =~ $DBREGEX ]] && echo "PASS" || echo "FAIL"
done < <(grep -v '#' databases/lan.db)

Upvotes: 1

Related Questions