Francis Batalla
Francis Batalla

Reputation: 83

BASH - If else, Regular expression, OR

My bash script is supposed to check if the user inputs two numbers. Each number should be preceded by either a + or a - sign. The first number should be four digits long, and the second number should be five digits long.

No matter what values I enter, the output is always Fail

Command-line statement to run the script:

$me add +1234 -12345

The script:

#!/bin/bash
#Script name add
if [ $1 != [\+\-][0-9][0-9][0-9][0-9] ] || 
   [ $2 != [\+\-][0-9][0-9][0-9][0-9][0-9] ]
  then
    echo Fail
else    
    echo Success
fi

Upvotes: 4

Views: 3844

Answers (3)

DavidDraughn
DavidDraughn

Reputation: 1131

You need to use double brackets to enable advanced functionality that is more similar to traditional programming languages. For instance, to use || instead of -o and && instead of -a. Double brackets are also required in order to perform pattern (matching.

Also, brackets should be used for the entire expression, not for each sub-expression separately and should include the ||.

I would use a line like:

if [[ $1 == [+-][0-9][0-9][0-9][0-9] && 
      $2 == [+-][0-9][0-9][0-9][0-9][0-9] ]]
  then
    echo "success"
else
    echo "fail"
fi

EDIT: using == instead of != (why be so negative?) and to remove references to regex (uses pattern matching).

Upvotes: 1

ormaaj
ormaaj

Reputation: 6577

POSIX-style tests ([) don't perform pattern matching at all. The != operator is a string comparison. ksh-style tests ([[)) perform pattern matching with reglular shell patterns using the == operator, and ERE matching with =~. (There is no !=~, but we can DeMorganify)

! [[ $1 =~ [-+][[:digit:]]{4} && $2 =~ [-+][[:digit:]]{5} ]]

To perform pattern matching in POSIX sh, the only option is the case statement.

Upvotes: 3

xaizek
xaizek

Reputation: 5252

I don't think there is a way (I was wrong, there is a way) to do pattern matching using if statement. case can be used for such things. Working example:

#!/bin/bash

#Script name add

case $1 in
    [+-][0-9][0-9][0-9][0-9]) r1='success' ;;
    *) r1='fail' ;;
esac
case $2 in
    [+-][0-9][0-9][0-9][0-9][0-9]) r2='success' ;;
    *) r2='fail' ;;
esac

if [ $r1 = 'fail' ] || [ $r2 = 'fail' ]
then
    echo Fail
else
    echo Success
fi

Upvotes: 1

Related Questions