bash中的动态case语句

时间:2011-01-14 03:28:55

标签: bash scripting bash-completion

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

例如,假设我有一个带有以下内容的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)。

有什么想法吗?

感谢。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:2)

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

1)确保列表与PIPE(|)分开。 IE浏览器。红色|绿色|蓝色

2)将你的case语句包装在eval中

例如:

valid="red|green|blue"

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

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

答案 3 :(得分:1)

你可以用几种不同的方式来解决这个问题:

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

答案 4 :(得分:0)

您可能必须尝试, 抱歉,如果您正在寻找,可能很抱歉(但我认为这对我有所帮助) 在这里,我遇到与动态语句一起使用shter 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

furthermore

希望帮助