bash case语句评估为字符串

时间:2010-02-17 19:12:47

标签: bash case functional-programming notation

我已经发现了函数式编程错误,所以自然对我来说已经不够了。 ;)

所以,在bash中可以写:

case $status in
  "foo") status="bar" ;;
  "baz") status="buh" ;;
   *) status=$status ;;
esac

但我害怕拼写错误,所以我更喜欢来写:

status=case $status in
  "foo") "bar" ;;
  "baz") "buh" ;;
  *) $status ;;
esac

第二种形式无效,因为案例评估的是上次执行的命令的退出代码,这完全不是我想要的。

是否容易实现我 寻找的目标?

3 个答案:

答案 0 :(得分:11)

如果您确定状态只有一行,您可以使用sed执行类似的操作:

status=$(echo "$status" | sed -e 's:^foo$:bar:' -e 's:^baz$:buh:')

你也可以通过bash的内置替换来获得一些东西。这几乎有效(我不知道有什么方法可以获得完全匹配):

status=${status/foo/bar}
status=${status/baz/buh}

如果你的目标只是为了更加“实用”(而不是让你的代码更具有防错性),你可以这样做:

status=$(
  case "$status" in
    ("foo") echo "bar" ;;
    ("baz") echo "buh" ;;
    (*) echo "$status" ;;
  esac)

虽然老实说,bash可能是最难尝试和功能的语言之一。它的确设计具有更强制性的思维模式,正如你无法轻易编写表达式所说明的那样。在第二个代码片段中看到我如何将其分成两个单独的语句?如果bash被设计为功能性的,那么你可以写下这样的东西:

status=${{status/baz/buh}/foo/bar}

工作。

我建议只使用bash来处理更简单的脚本,而对于更复杂的东西则使用像Python或Ruby这样的东西。他们会让你编写更多功能代码,而不必经常与语言搏斗。

答案 1 :(得分:3)

status="baz"
status=$(case $status in
  "foo") echo "bar" ;;
  "baz") echo "buh" ;;
  *) echo $status ;;
esac)
echo "status: $status"

输出

$ ./shell.sh
status: buh

答案 2 :(得分:-1)

Bash 4有关联数组:

# setup
unset vals i
indices=(foo baz)
val=(bar buh)
declare -A vals             # associative
for index in ${indices[@]}
do
    vals[$index]=${val[i++]}
done

$ # demos
$ status="foo"
$ status=${vals:-$status}
$ echo $status
bar
$ status="not found"
$ status=${vals:-$status}
$ echo $status
not found