4

I'm trying to use bash to find if a short string is present in any string "sets". For example,

FRUIT="apple banana kiwi melon"
VEGETABLE="radish lettuce potato"
COLOR="blue red yellow green brown"

MY_CHOICE="kiwi"
MY_CHOICE_GROUP="?"

How can I set MY_CHOICE_GROUP to FRUIT?

I tried to use this StackOverflow solution, but it only works with a single string set.

Originally, I was using arrays to store the options in a set, but given the way bash handles iteration over arrays, it seems a string search would be more efficient.

Many thanks!

Community
  • 1
  • 1
hao_maike
  • 2,929
  • 5
  • 26
  • 31

3 Answers3

6
  1. The simplest way, IMO, would be to just hardcode a bunch of case...esac labels.

    #!/bin/bash
    function lookup()
    {
        case "$1" in
            apple|banana|kiwi|melon)
                echo "FRUIT"
                ;;
    
            radish|lettuce|potato)  
                echo "VEGETABLE"
                ;;
    
            blue|red|yellow|green|brown)   
                echo "COLOR"
                ;;
        esac
    }
    
    MY_CHOICE="kiwi"
    MY_CHOICE_GROUP=$(lookup "$MY_CHOICE")
    
    echo $MY_CHOICE: $MY_CHOICE_GROUP
    

    See it live on ideone

  2. Otherwise, consider associative arrays, see it live on ideone:

    #!/bin/bash
    declare -A groups
    
    groups["apple"]="FRUIT"
    groups["banana"]="FRUIT"
    groups["kiwi"]="FRUIT"
    groups["melon"]="FRUIT"
    
    groups["radish"]="VEGETABLE"
    groups["lettuce"]="VEGETABLE"
    groups["potato"]="VEGETABLE"
    
    groups["blue"]="COLOR"
    groups["red"]="COLOR"
    groups["yellow"]="COLOR"
    groups["green"]="COLOR"
    groups["brown"]="COLOR"
    
    MY_CHOICE="kiwi"
    MY_CHOICE_GROUP=${groups[$MY_CHOICE]}
    
    echo $MY_CHOICE: $MY_CHOICE_GROUP
    
sehe
  • 374,641
  • 47
  • 450
  • 633
1

Only shortening a bit @sehe's answer:

#!/bin/bash

declare -A groups
mkaso() { val="$1"; shift; for key in "$@"; do groups["$key"]="$val"; done; }

mkaso FRUIT apple banana kiwi melon
mkaso VEGETABLE radish lettuce potato
mkaso COLOR blue red yellow green brown
#declare -p groups

MY_CHOICE="kiwi"
MY_CHOICE_GROUP=${groups[$MY_CHOICE]}
echo $MY_CHOICE: $MY_CHOICE_GROUP
clt60
  • 62,119
  • 17
  • 107
  • 194
1
#!/bin/bash
FRUIT="apple banana kiwi melon"
VEGETABLE="radish lettuce potato"
COLOR="blue red yellow green brown"

MY_CHOICE="kiwi"

for group in VEGETABLE COLOR FRUIT
do
    if [[ ${!group} == *${MY_CHOICE}* ]]; then
        MY_CHOICE_GROUP=$group
        break
    fi
done

echo $MY_CHOICE_GROUP
pmoosh
  • 60
  • 5