Is there an "in" operator in bash/bourne?
You can use case
... esac
$ cat in.sh
#!/bin/bash
case "$1" in
"cat"|"dog"|"mouse")
echo "dollar 1 is either a cat or a dog or a mouse"
;;
*)
echo "none of the above"
;;
esac
Ex.
$ ./in.sh dog
dollar 1 is either a cat or a dog or a mouse
$ ./in.sh hamster
none of the above
With ksh
, bash -O extglob
or zsh -o kshglob
, you could also use an extended glob pattern:
if [[ "$1" = @(cat|dog|mouse) ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
With bash
, ksh93
or zsh
, you could also use a regular expression comparison:
if [[ "$1" =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
else
echo "none of the above"
fi
There is not an "in" test in bash, but there is a regex test (not in bourne):
if [[ $1 =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
And usually written using a variable (less problems with quoting):
regex='^(cat|dog|mouse)$'
if [[ $1 =~ $regex ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
For an older Bourne shell you need to use a case match:
case $1 in
cat|dog|mouse) echo "dollar 1 is either a cat or a dog or a mouse";;
esac
Using a case
is fine and well if you have a fixed set of pets you want to match against. But it won't work if you need to build the pattern in runtime, as case
doesn't interpret alternation from within expanded parameters.
This will match only the literal string cat|dog|mouse
:
patt='cat|dog|mouse'
case $1 in
$patt) echo "$1 matches the case" ;;
esac
You can, however, use a variable with the regular expression match. As long as the variable isn't quoted, any regex operators within it have their special meanings.
patt='cat|dog|mouse'
if [[ "$1" =~ ^($patt)$ ]]; then
echo "$1 matches the pattern"
fi
You could also use associative arrays. Checking if a key exists in one is the closest thing to an in
operator that Bash gives. Though the syntax is a bit ugly:
declare -A arr
arr[cat]=1
arr[dog]=1
arr[mouse]=1
if [ "${arr[$1]+x}" ]; then
echo "$1 is in the array"
fi
(${arr[$1]+x}
expands to x
if arr[$1]
is set, empty otherwise.)