21

我发现了函数式编程错误,所以自然对我来说没有什么是足够好的了。;)

因此,在 bash 中可以这样写:

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

但我害怕错别字,所以我宁愿写:

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

第二种形式是无效的,因为 case 评估为最后执行的命令的退出代码,这根本不是我想要的。

是否有简单的技巧来实现我正在寻找的东西?

4

3 回答 3

23

如果你确定 status 只会是一行,你可以用 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 之类的东西。它们可以让你编写更多功能代码,而不必不断地与语言搏斗。

于 2010-02-17T19:36:02.570 回答
5
status="baz"
status=$(case $status in
  "foo") echo "bar" ;;
  "baz") echo "buh" ;;
  *) echo $status ;;
esac)
echo "status: $status"

输出

$ ./shell.sh
status: buh
于 2010-02-18T00:43:49.180 回答
-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
于 2010-02-17T20:47:56.770 回答