
Я ищу оператор «in», который работает примерно так:
if [ "$1" in ("cat","dog","mouse") ]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Очевидно, что это гораздо более короткое утверждение по сравнению, скажем, с использованием нескольких проверок «или».
решение1
Вы можете использовать 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
Бывший.
$ ./in.sh dog
dollar 1 is either a cat or a dog or a mouse
$ ./in.sh hamster
none of the above
С помощью ksh
, bash -O extglob
или zsh -o kshglob
вы также можете использовать расширенный шаблон глобуса:
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
С помощью bash
, ksh93
или zsh
вы также можете использовать сравнение регулярных выражений:
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
решение2
В bash нет проверки «in», но есть проверка regex (в bourne ее нет):
if [[ $1 =~ ^(cat|dog|mouse)$ ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
И обычно записывается с использованием переменной (меньше проблем с кавычками):
regex='^(cat|dog|mouse)$'
if [[ $1 =~ $regex ]]; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
Для более старой оболочки Bourne необходимо использовать соответствие регистру:
case $1 in
cat|dog|mouse) echo "dollar 1 is either a cat or a dog or a mouse";;
esac
решение3
Использование a case
прекрасно и хорошо, если у вас есть фиксированный набор питомцев, с которыми вы хотите сопоставить. Но это не сработает, если вам нужно построить шаблон во время выполнения, так как case
не интерпретирует чередование из расширенных параметров.
Это будет соответствовать только буквальной строке cat|dog|mouse
:
patt='cat|dog|mouse'
case $1 in
$patt) echo "$1 matches the case" ;;
esac
Однако вы можете использовать переменную с регулярным выражением. Пока переменная не заключена в кавычки, любые операторы регулярных выражений внутри нее имеют свои особые значения.
patt='cat|dog|mouse'
if [[ "$1" =~ ^($patt)$ ]]; then
echo "$1 matches the pattern"
fi
Вы также можете использовать ассоциативные массивы. Проверка наличия ключа в одном из них — это самое близкое к in
оператору, которое предоставляет Bash. Хотя синтаксис немного уродлив:
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}
расширяется до x
, если arr[$1]
установлено, в противном случае остается пустым.)
решение4
grep
подход.
if echo $1 | grep -qE "^(cat|dog|mouse)$"; then
echo "dollar 1 is either a cat or a dog or a mouse"
fi
-q
чтобы избежать вывода на экран (быстрее вводить, чем>/dev/null
).-E
для расширенных аспектов регулярных выражений(cat|dog|mouse)
это необходимо.^(cat|dog|mouse)$
соответствует любым строкам, начинающимся (^
) с кошки, собаки или мыши ((cat|dog|mouse)
), за которыми следует конец строки ($
)