2

我试图弄清楚如何在 bash 脚本中创建动态案例语句。

例如,假设我有一个 awk 语句的输出,其内容如下

red
green
blue

在这种情况下,输出可以随时更改。

如果此 awk 输出中包含一个值,我将尝试执行不同的逻辑。

因此,如果上面的数据在 $list 中,那么我在概念上想做类似的事情:

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

我正在尝试使用它来构建动态自定义选项卡完成功能(有关一些背景信息,请参见http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2)。

有任何想法吗?

谢谢。

4

6 回答 6

6

您可以通过执行以下操作在 bash 中创建动态 case 语句:

1) 确保列表是 PIPE (|) 分隔的。IE。红色|绿色|蓝色

2)将您的案例陈述包装在评估中

例如:

valid="red|green|blue"

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

这适用于简单的变量处理,我不能保证这在所有情况下都有效。

于 2013-11-04T15:45:31.403 回答
2

你不能用 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
于 2011-01-14T03:44:12.047 回答
2

声明可能不是这项工作的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
于 2011-01-14T03:49:19.253 回答
1

您可以通过几种不同的 hacky 方式来解决此问题:

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
于 2011-01-14T05:04:47.983 回答
0

您是否必须尝试,对不起,如果这可能是你们正在寻找的oot/didnt,(但我认为这对我有帮助)在这里我在使用带有动态语句的wheter sh case时遇到同样的问题

而我已经运行了一些以动态列出的参数作为输入的函数,那么如果内部/可用的函数没有,它将返回退出 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

此外

希望帮助

于 2020-08-24T05:23:10.323 回答
0

使用 bash 4 中可用的标准工具管理这一点非常简单。数组 OptionList 的大小可以自由变化。

OptionList=(Fred Wilma Barney)
PS3='Choose a character : '
select opt in "${OptionList[@]}" "Quit"; do
    case "$REPLY" in
        $((${#OptionList[@]}+1))) echo "Goodbye!"; exit;;
    esac
    [ $REPLY -gt $((${#OptionList[@]}+1)) -o $REPLY -lt 1 ] && echo "Invalid selection" || break
done

echo "you chose ${OptionList[(($REPLY-1))]}"
于 2021-08-24T10:13:48.070 回答