shell 如何在一个case中检查多个变量?[关闭]

qqrboqgw  于 2023-11-21  发布在  Shell
关注(0)|答案(2)|浏览(113)

已关闭。此问题需要details or clarity。目前不接受回答。
**要改进此问题吗?**通过editing this post添加详细信息并阐明问题。

3天前关闭。
Improve this question
我想知道是否有可能在case语句中使用多个变量,这样我就不必两次维护大量的行(它们应该是相同的)?
例如,我想检查LC_ALLLANG中的一个(或两个都可以)是否以es开头:

  • 由于我在伪代码中使用逻辑“或”(||),我希望它在shell中照常工作.检查第一个变量是否匹配任何情况,如果不检查第二个变量是否匹配任何情况。
case "${LC_ALL}" || "${LANG}" in    # something like this would come in handy
  "es"*)
    # numerous lines ABC
  ;;
  "VALUE1" | "VALUE2")              # i know 2 different VALUES are possible, but not helpful in my situation
    # numerous lines XYZ
  ;;
esac

字符串
当然,我已经阅读了https://www.gnu.org/software/bash/manual/bash.html#index-case,并在网上搜索了一些类似的例子,但不幸的是,在这方面没有找到任何东西。
是的,我也发现了Multiple variables in a CASE statement,但不知何故,它似乎是一个完全不同的方法(我不完全理解)。

**额外的问题:**为什么只有1个竖线(|)用于2个值之间,而不是2(||),就像它是一个逻辑“或”在命令等?

5kgi1eie

5kgi1eie1#

如果代码不能实现你想要的功能,那就不是解释你真正想要的东西的好方法。

case ${LC_ALL}${LANG} in
  *"es"* )
    # numerous lines
  ;;
  *"VALUE"[12]*)
    # numerous lines
  ;;
esac

字符串
如果您想确保检查的是整个值,可以尝试

case :${LC_ALL}:${LANG}: in
  *:"es"* )  # or perhaps *:"es":*?
    # numerous lines
  ;;
  *:"VALUE"[12]:*)
    # numerous lines
  ;;
esac


(当然,如果值可以包含冒号,可能会选择一个不同的冒号。在近似重复中,他们使用了加号)。
......或者,也许你的意思是

for value in "$LANG" "$LC_ALL"; do
    case $value in
      "es"* )
        # numerous lines
        break
      ;;
      "VALUE"[12] )
        # numerous lines
        break
      ;;
    esac
done


如果两个值都不匹配任何模式,也许你还想安排某种后备;也许试试这个稍微复杂一点的版本:

found=""

for value in "$LANG" "$LC_ALL"; do
    case $value in
      "es"* )
        # numerous lines
        found=$value
        break
      ;;
      "VALUE"[12] )
        # numerous lines
        found=$value
        break
      ;;
    esac
done
case $found in
    '') echo "$0: catastrophic failure! Red alert! Mayhem!" >&2
        exit 69;;
esac


如果您想跟踪哪个 * 变量 * 匹配,而不是哪个值,也许还可以查看indirect expansion.
我不认为语法上有什么好的理由让|优于||,但也没有什么好的理由让|相反。替代方案是glob模式,而不是命令。x | y已经意味着其他东西,所以他们必须在OR命令之间使用||,但对glob没有这样的限制。

wf82jlnq

wf82jlnq2#

如果我明白了你实际上想完成的事情的要点,有一种更强大的方法。
您可能希望使用常见的 *nix程序locale来获取语言名称(libc-bin [Ubuntu]或glibc包[Slackware]的一部分)。
这个程序以某种我不知道的顺序读取LC_ALLLANGLC_MESSAGES,并计算应该以标准化的方式应用什么设置。**如果你试图在你的shell脚本中重新实现locale,你会有一段糟糕的时间。
然后你只需要关闭一个subshell扩展:

case $(locale lang_ab) in
    'en')
        ;;
    'es')
        ;;
esac

字符串
您也可以键入完整的语言名称。

case $(locale language) in
    *'English') # en_US, en_NZ, en_CA, en_GB, etc.
        ;;
    *'Spanish') # es_ES, es_CO, es_EU, es_MX, etc.
        ;;
esac


如果你愿意,你也可以关闭个别语言名称:

case $(locale language) in
    'American English') # i.e. en_US
        ;;
    'Mexican Spanish') # i.e. es_MX
        ;;
    'European Spanish') # i.e. es_ES
        ;;
esac


你可以向locale询问各种各样的事情,比如用户的语言环境设置如何指定数字和日期的格式,甚至如何对用户说“是”:

$ LANG=en_US locale yesstr
yes
$ LANG=es_ES locale yesstr
sí


更多关键字可以在locale(5)man 5 locale)下找到
但是,如果你想简单起见,或者你没有安装locale,你可以使用${LC_ALL:-$LANG}来表示“如果$LC_ALL未设置或为空,则默认为$LANG”:

case ${LC_ALL:-$LANG} in
  'es'*)
  ;;
  'VALUE1' | 'VALUE2')
  ;;
esac

相关问题