简体   繁体   English

多个单词作为bash中的可能变量

[英]Multiple words as a possible variable in bash

The line Hi=("Hi" "Hello" "Hey") has the possible inputs. Hi =(“ Hi”“ Hello”“ Hey”)行具有可能的输入。 I've tried adding a comma between the words and that does not work either. 我试过在单词之间添加逗号,但这也不起作用。 If hi , hello , or hey are typed in, I need it to echo "Hi". 如果输入hihellohey,则需要它回显“ Hi”。 Right now only Hi works. 目前只有Hi可以运作。 I guess what I'm looking for is a way to make "synonyms" for a word. 我猜我正在寻找一种为单词制作“同义词”的方法。 The ability to substitute a one word for another. 用一个词代替另一个词的能力。

    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

I know I could use 我知道我可以用

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

but that will get to be way too long. 但这太长了。

If your target is bash 4.0 or newer, an associative array will work: 如果目标是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

This is an O(1) lookup, making it faster than an O(n) loop-based traversal. 这是一个O(1)查找,使其比基于O(n)循环的遍历更快。


That said, if the list of items you're matching against is hardcoded, just use a case statement: 也就是说,如果您要匹配的项目列表是硬编码的,则只需使用case语句即可:

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

This also has the advantage of being compatible with any shell compliant with POSIX sh. 这还具有与任何兼容POSIX sh的外壳兼容的优点。

Take a look at this variant: 看一下这个变体:

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

The thing is: use a flag + a for loop. 问题是:使用标志+ for循环。 If the flag is set (=1), then the TextInput is equal to something in your Hi array. 如果设置了标志(= 1),则TextInput等于Hi数组中的值。

Depending on your needs, you can also use a switch: 根据您的需要,您还可以使用开关:

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

This allows you to also specify patterns. 这还允许您指定模式。

Using bash's pattern matching: 使用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

I use parentheses here to spawn a subshell, so changes to the IFS variable don't affect the current shell. 我在此处使用括号来生成子外壳,因此对IFS变量的更改不会影响当前外壳。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM