测试 Bash 变量中任何相关值系列

测试 Bash 变量中任何相关值系列

如果之前已经回答过这个问题,我深表歉意,但我在网上找不到太多内容。

这就是我想要实现的目标:

if [[ "${hostname}" = (foo | bar)servername(01 | 02 | 03) ]]; then
  var="foobarfoo"
fi

这样,以下任何一个都将满足条件:fooservername01、barservername02、fooservername03、barservername03 等。

我以一种效率低得多的方式完成了这一点:

if [[ ${hostname} == "fooservername01" ]] || [[ ${hostname} == "fooservername02" ]] || [[ ${hostname} == "fooservername03" ]] || [[ ${hostname} == "barservername01" ]] || [[ ${hostname} == "barservername02" ]] || [[ ${hostname} == "barservername03" ]]; then
  var="foobarfoo"
fi

但我希望优化/简化代码。

任何见解将不胜感激,因为我对 bash 脚本甚至一般脚本仍然很陌生。

答案1

您可以几乎完全按照您所写的那样进行操作。当你使用时[[然后==用途模式匹配在右手侧。在 Bash 模式中,您可以使用以下方式匹配一组模式之一@(a|b|c)

if [[ "${hostname}" = @(foo|bar)servername@(01|02|03) ]]; then

这与您确定的每个案例相匹配。@( ... | ... )匹配其中任何一个|- 分隔的模式。你也能使用其他 glob*?[character classes]以及进一步的复合模式来实现重复、可选或否定模式。

使用这些扩展模式需要extglob启用 shell 选项。如果它尚未启用(您将收到语法错误),您可以通过以下方式启用它:

shopt -s extglob

在你if出现之前的任何地方。


如果您愿意并且对它们更熟悉,您也可以使用任意扩展正则表达式通过使用=~运算符代替==.

答案2

case ${hostname%"servername0"[123]} in
("$hostname") ! :;; 
(foo|bar) ;;
(*) ! :;; esac

答案3

我认为你应该用grep它。例如:

HOST_REGEX='(foo|bar)servername(01|02|03)'

if grep -qE "${HOST_REGEX}" <<< "${hostname}"
then
  var="foobarfoo"
fi

一行:

grep -qE '(foo|bar)servername(01|02|03)' <<< "${hostname}" && var="foobarfoo"

答案4

您可以使用=~测试运算符。这接受(不带引号的)扩展正则表达式(类似于egrep)。

if [[ "$hostname" =~ (foo|bar)servername(01|02|03) ]]
then echo matches
else echo no match
fi

相关内容