Динамический оператор case в bash

Я пытаюсь понять, как создать динамический оператор case в сценарии bash.

Например, допустим, у меня есть вывод оператора awk со следующим содержимым

red
green
blue

В этом сценарии выходные данные могут измениться в любое время.

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

Итак, если приведенные выше данные находятся в $list, то я концептуально хотел бы сделать что-то вроде:

case "${my_var}" in
    $list)
        .....
    something_else)
        .....
esac

Я пытаюсь использовать это для создания динамической пользовательской функции завершения табуляции (см. debian-administration.org/article/An_introduction_to_bash_completion_part_2 для дополнительной информации).

Любые идеи?

Спасибо.


person infra.user    schedule 14.01.2011    source источник
comment
Интересный вопрос: как вы собираетесь указывать, что входит в ..... часть дела для каждого из действий?   -  person Jonathan Leffler    schedule 14.01.2011


Ответы (5)


Оператор case, вероятно, не подходит для этой работы. Если вы сохраните вывод awk в массиве, то вы можете прокрутить массив, чтобы найти, есть ли в нем выбор, и в качестве бонуса также можете выяснить, какой это индекс.

#!/bin/bash

# Store command output in an array so each word is a separate array item.    
list=($(echo $'red\ngreen\nblue'))
my_var=blue

for ((i = 0; i < ${#list}; i++)); do
    if [[ ${list[$i]} = $my_var ]]; then
        echo "found at index $i"
        break
    fi
done

if ((i == ${#list})); then
    echo "not found"
fi
person John Kugelman    schedule 14.01.2011

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

1) убедитесь, что список разделен PIPE (|). IE. красный|зеленый|синий

2) оберните оператор case в eval

Например:

valid="red|green|blue"

eval "case \"$choice\" in
    $valid)
        echo do something good here
        ;;
    *)
        echo invalid colour
        ;;
esac"

Это работает для простой обработки переменных, я не могу гарантировать, что это будет работать во всех случаях.

person Jason H    schedule 04.11.2013

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

# stub to simulate this arbitrary call
my_awk_command() { printf '%s\n' red green blue; }
# helper to check list membership
list_contains() {
  local tgt="$1"; shift
  while (( $# )); do
    if [[ $1 = "$tgt" ]] ; then
      return 0
    fi
    shift
  done
  return 1
}

# the below is Bash 4 functionality; see BashFAQ #1 on how to replace it
readarray -t awk_output < <(my_awk_command)

if list_contains "$my_var" "${my_awk_command[@]}"; then
  ...something...
elif [[ "$my_var" = something_else ]] ; then
  ...something else...
fi
person Charles Duffy    schedule 14.01.2011

Вы можете подойти к этому несколькими разными хакерскими способами:

pattern=($(awk_command))     # red\ngreen\nblue\n
saveIFS=$IFS
IFS='|'
pattern="^(${pattern[*]})$"  # ^(red|green|blue)$  (perhaps hackish)
IFS=$saveIFS

# simple regex match if statement (not hackish)
if [[ $var =~ $pattern ]]
then
    do_something
fi

# or a backwards case statement (very hackish)
case 1 in    # this could be a variable or a command substitution
    $([[ $var =~ $pattern]] && echo 1) )  # the echo 1 could be another command or the 1 could be yet another variable
        do_something;;
    * )
        do_default;;
esac
person Dennis Williamson    schedule 14.01.2011

возможно, вам придется попробовать, извините, если это может быть oot / вы, ребята, не искали, (но я думаю, что это поможет мне) здесь у меня те же проблемы с использованием случая sh с динамическим оператором

тогда как у меня есть какая-то функция с динамическим параметром в качестве входных данных, тогда, если внутри/доступной функции нет, она вернет выход 1 или запрошенный недоступен

вот так.

myfuncA(){
   echo this funcA
}

myfuncB(){
   echo this funcB
}


dynamicCase(){
   for areWe in $1; do
      my$areWe && echo "$areWe success" || echo "no function $1 available"
   done
}

anotherDyCase(){
   while IFS=read -r $areWe; do
      my$areWe && echo "$areWe success" || echo "no function $1 "
   done <<< $1
}

тестовая поездка:

myListedDynamic="funcA\nfuncB\nfuncC"
// funcA funcB funcC


dynamicCase $myListedDynamic
// success
// success
// no function available

более того

надеюсь помочь

person Sandiko    schedule 24.08.2020