【问题标题】:BASH Not In CaseBASH 不以防万一
【发布时间】:2014-03-22 01:37:16
【问题描述】:

我正在尝试找出一种在案例中执行 NOT 子句的合理方法。我这样做的原因是 遇到情况时转码,也就是如果我打了一个avi,没有理由再把它变成一个avi,我可以 只需将其移开(这是我的案例基础的范围应该做的)。反正我有一些 我写出的那种 proto 代码给出了我正在尝试做的事情的要点。

#!/bin/bash
for i in $(seq 1 3); do 

    echo "trying: $i"

    case $i in
        ! 1)    echo "1" ;;     # echo 1 if we aren't 1
        ! 2)    echo "2" ;;     # echo 2 if we aren't 2
        ! 3)    echo "3" ;;     # echo 3 if we aren't 3
        [1-3]*) echo "! $i" ;;  # echo 1-3 if we are 1-3
    esac

    echo -e "\n"

done

预期的结果会是这样的

2 3 ! 1
1 3 ! 2
1 2 ! 3

非常感谢您的帮助,谢谢。

【问题讨论】:

  • 您意识到case 在设计上每次调用只执行一件事?
  • ...另外,$(seq 1 3) 不可移植——seq 不是 POSIX 标准命令,许多平台都没有它。最好使用 C 风格的循环,即。 for ((i=1; i<=3; i++)); do
  • @CharlesDuffy 我没有,我认为它像 php 等更灵活
  • 实际上,bash 的case 的工作方式是更常见的;它与 C 和 Java 的行为相同(除了缺少失败,这通常被认为是令人困惑的并且是错误/误读的常见来源)。
  • (更新到上面的评论:bash 的案例现在确实在 4.x 系列中可用;它的行为仍然与 C、Java 等一致。选择一个入口点)。

标签: bash case


【解决方案1】:

您可以使用 extglob 扩展来做到这一点。

$ shopt -s extglob
$ case foo in !(bar)) echo hi;; esac
hi
$ case foo in !(foo)) echo hi;; esac
$

【讨论】:

  • 不过,在同一个 case 语句中使用多个模式时,它的行为将无法达到预期效果。
  • @CharlesDuffy 啊,真的。好吧,我将保持原样,否定匹配仍然是一个有用的东西。
【解决方案2】:

这与case 的设计相反,它只执行第一个匹配。如果你想在多个匹配上执行(并且在你的设计中,3 想要在12 上执行的东西),那么case 是错误的构造.使用多个 if 块。

[[ $i = 1 ]] || echo "1"
[[ $i = 2 ]] || echo "2"
[[ $i = 3 ]] || echo "3"
[[ $i = [1-3]* ]] && echo "! $i"

因为 case 只执行第一个匹配,所以只有一个“不匹配”处理程序才有意义;这就是*) 失败的用途。

【讨论】:

  • 接受和赞成,简短的 if 的工作也一样,实际上只是在后台做,但你打败了我 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2018-10-16
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多