Search code examples
bashif-statementlogic

Bash if then statement for multiple, clustered conditions


I am trying to write a command to only run an R script if certain conditions are met.

The conditions are clustered as follows (this is fake data, but the question is the same):

  1. If the first argument ($1) contains dog AND the second argument ($2) > 10, run the elderly.R script
  2. If $1 contains cat AND $2 > 12, run the elderly.R script

I have tried 2 methods:

Method 1:

if [[ $1 =~ dog ]] && [ $2 -gt 10 ]] || if [[ $1 =~ cat ]] && [ $2 -gt 12 ]]; 
then 
Rscript elderly.R
fi

Method 2:

if [[ $1 =~ dog ]] && [ $2 -gt 10 ]]; 
then 
Rscript elderly.R
elif [[ $1 =~ cat ]] && [ $2 -gt 12 ]];
then
Rscript elderly.R
else
echo "parameters not in range"
fi

How do I subset the first 2 and second two if arguments?

Right now, Method 1 is reading it as if the first argument is dog OR cat and the age is greater than 10, run the R script. Method 2, however, do not output anything when

./test.sh cat 13

is run. (test.sh is just a placeholder for the script name)

Any and all help is appreciated!


Solution

  • Consider writing short functions to help you:

    old_dog () {
        [[ $1 == dog ]] && (($2 > 10))
    }
    old_cat () {
        [[ $1 == cat ]] && (($2 > 12))
    }
    
    if old_dog "$@" || old_cat "$@"; then
        Rscript elderly.R
    else
        echo "parameters not in range"
    fi
    

    Or, with less duplication

    old_animal () {
        case $1 in
            dog) (($2 > 10)) ;;
            cat) (($2 > 12)) ;;
            *)   false ;;
        esac
    }
    
    if old_animal "$@"; then
        Rscript elderly.R
    else
        echo "parameters not in range"
    fi
    

    What you were missing: too many ifs; not enough grouping

    if ([[ $1 =~ dog ]] && [ $2 -gt 10 ]) || ([[ $1 =~ cat ]] && [ $2 -gt 12 ]);
    #  ^................................^    ^................................^