bash: проверить, установлен ли $ WORD

54

Я ищу в конструкции bash, чтобы решить, является ли переменная $WORDодним из определенных слов. Мне нужно что-то вроде этого:

if "$WORD" in dog cat horse ; then 
    echo yes
else
    echo no
fi

у bash есть такая конструкция? Если нет, то что будет ближе всего?

Мартин Вегтер
источник

Ответы:

57

Это решение Bash-only (> = version 3), использующее регулярные выражения:

if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

Если ваш список слов длинный, вы можете сохранить его в файле (по одному слову в строке) и сделать это:

if [[ "$WORD" =~ $(echo ^\($(paste -sd'|' /your/file)\)$) ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

Одно предупреждение с файловым подходом:

  • Это сломается, если файл имеет пробел. Это может быть исправлено чем-то вроде:

    sed 's/[[:blank:]]//g' /your/file | paste -sd '|' /dev/stdin

Спасибо @terdon за напоминание о том, чтобы правильно закрепить шаблон с помощью ^и $.

Джозеф Р.
источник
1
И shopt -s nocasematchможет помочь, если вы хотите, чтобы поиск не учитывал регистр.
Скиппи ле Гран Гуру
1
Обратите внимание, что вы должны использовать [[и ]]- [и ]не достаточно.
Грег Дубицки
я искал 'oneliner', чтобы проверить мой аргумент сценария, и это сработало отлично. благодарю вас! [[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
RASG
76
case $word in
    dog|cat|horse) echo yes;;
    *)             echo no;;
esac
Джон Кугельман поддерживает Монику
источник
11

Как насчет:

#!/usr/bin/env bash

WORD="$1"
for w in dog cat horse
do
  if [ "$w" == "$WORD" ] 
  then
      yes=1
      break
  fi
done;
[ "$yes" == "1" ] && echo "$WORD is in the list" || 
                     echo "$WORD is not in the list"

Затем:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list
Тердон
источник
3
if (echo "$set"  | fgrep -q "$WORD")
BrenoZan
источник
1
Осторожно, это возвращает истину , если $WORDпусто, он будет соответствовать , если WORD=caили WORD=ogили подобным , и я предполагаю , что вы имели в виде echo ${set[@]}.
Terdon
просто добавьте -w к grep, чтобы избежать частичных слов
BrenoZan
1

Вы можете определить функцию bash для этого:

function word_valid() 
{ 
  if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then
    echo no
  else
    echo yes
  fi
}

Затем используйте просто так:

word_valid cat
suspectus
источник
1

Я искал решение «в одну строку» для проверки аргумента сценария и использовал ответ Джозефа Р. выше, чтобы придумать:

[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }

RASG
источник
0

Это сработало для меня:

#!/bin/bash
phrase=(cat dog parrot cow horse)
findthis=parrot

for item in ${phrase[*]}
do
    test "$item" == "$findthis" && { echo "$findthis found!"; break; }
done
Хавьер
источник
0

Возможно, вы захотите поместить список слов в файл, если вы часто меняете список или хотите, чтобы он использовался несколькими сценариями. И вам может понадобиться поместить слова в файл, если список становится слишком длинным для управления в сценарии. Тогда вы можете сказать

if fgrep qx "$WORD" word_list
Скотт
источник
нет, я не хочу, чтобы мой список был в файле
Мартин Вегтер
0

Если слова представляют собой список, в котором значения разделены новой строкой, вы можете сделать следующее:

WORDS="$(ls -1)"
if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then
    echo yes
else
    echo no
fi
Mitar
источник
0

Вы можете использовать fgrep, чтобы указать все разрешенные слова:

if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then 
    echo yes
else
    echo no
fi

-wФлаг соответствует только полные слова, то -qфлаг позволяет работать тихо (потому что все , что нужно это возвращаемое значение для если заявление использования), и каждый -eшаблон задает шаблон , чтобы позволить.

fgrepверсия grep, которая выполняет обычное сопоставление строк вместо сопоставления с регулярным выражением Если у вас есть grep, вы должны иметь fgrep, но если нет, то это идентично использованию grepс -Fфлагом (так что вы просто замените fgrep -wqвыше на grep -Fwq).

Кристофер Шроба
источник