Несколько слов как возможная переменная в bash

Строка Hi=("Hi", "Hello", "Hey") содержит возможные входные данные. Я попытался добавить запятую между словами, и это тоже не работает. Если введены привет, привет или эй, мне нужно повторить "Привет". Щас только привет работает. Я думаю, что я ищу способ сделать "синонимы" для слова. Возможность заменить одно слово другим.

    clear; echo
    shopt -s nocasematch
    echo; read -p "    > " TextInput

    Hi=("Hi" "Hello" "Hey")

     if [[ "$TextInput" == $Hi ]]; then
    clear; echo; echo
    echo -e "    >> Hi"
    echo

     else
    clear; echo; echo
    echo -e "    >> Error"
    echo
    fi

Я знаю, что мог бы использовать

     if [[ "$TextInput" == "Hi" ]] || [[ "$TextInput" == "Hello" ]] || [[ "$TextInput" == "Hey" ]]; then

но это будет слишком долго.

4 ответа

Решение

Если ваша цель - bash 4.0 или новее, будет работать ассоциативный массив:

TextInput=Hello
declare -A values=( [Hi]=1 [Hello]=1 [Hey]=1 )

if [[ ${values[$TextInput]} ]]; then
  echo "Hi there!"
else
  echo "No Hi!"
fi

Это поиск O(1), что делает его быстрее, чем обход через O(n).


Тем не менее, если список элементов, с которыми вы сопоставляете, жестко закодирован, просто используйте оператор case:

case $TextInput in
  Hi|Hello|Hey) echo "Hi there!" ;;
  *)            echo "No Hi!     ;;
esac

Это также дает преимущество совместимости с любой оболочкой, совместимой с POSIX sh.

Взгляните на этот вариант:

TextInput="Hello"
Hi=("Hi" "Hello" "Hey")

flag=0

for myhi in ${Hi[@]}; do
    if [[ "$TextInput" == "$myhi" ]]; then
        flag=1
        break
    fi
done

if [[ $flag == 1 ]]; then
    echo "Hi there!"
else
    echo "No Hi!"
fi

Дело в том, что используйте флаг + цикл for. Если флаг установлен (=1), то TextInput равно что-то в вашем Hi массив.

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

case "$input" in
  "Hi"|"He"*)
    echo Hello
    ;;
  *)
    echo Error
    ;;
  esac

Это позволяет вам также указать шаблоны.

Используя сопоставление с образцом bash:

$ Hi=(Hi Hello Hey)
$ input=foo
$ if (IFS=:; [[ ":${Hi[*]}:" == *:"$input":* ]]); then echo Y; else echo N; fi
N
$ input=Hey
$ if (IFS=:; [[ ":${Hi[*]}:" == *:"$input":* ]]); then echo Y; else echo N; fi
Y

Здесь я использую круглые скобки для создания подоболочки, поэтому изменения в переменной IFS не влияют на текущую оболочку.

Другие вопросы по тегам