Bash案例语句中的正则表达式

时间:2012-03-09 09:02:39

标签: regex bash case glob

我正在使用以下脚本,它使用case语句来查找服务器。

    #!/bin/bash
SERVER=$1;
echo $SERVER | egrep "ws-[0-9]+\.host\.com";
case $SERVER in
ws-[0-9]+\.host\.com) echo "Web Server"
;;
db-[0-9]+\.host\.com) echo "DB server"
;;
bk-[0-9]+\.host\.com) echo "Backup server"
;;
*)echo "Unknown server"
;;
esac

但它不起作用。正则表达式正在与egrep合作,但不与案例合作。样本O / P

./test-back.sh ws-23.host.com
ws-23.host.com
Unknown server

任何想法?

7 个答案:

答案 0 :(得分:38)

Bash案例不使用正则表达式,只使用shell pattern matching

因此,您应该使用模式ws-[0-9]+\.host\.com(或ws*.host.com,而不是正则表达式ws-+([0-9]).host.com,但这看起来有点先进,我从未尝试过: - )

答案 1 :(得分:9)

case只能使用globs。如果你想进行正则表达式匹配,那么你需要使用一系列if-then-else-elif-fi语句,[[

答案 2 :(得分:8)

如果您想断言*确实与ws*.host.com中的数字匹配,并希望使用case代替ifelifelif ... 你可以使用类似的东西:

case $SERVER in
  ws-[0123456789][0123456789][0123456789].host.com) echo "Web Server" ;;
  db-[0123456789][0123456789][0123456789].host.com) echo "DB server" ;;
  bk-[0123456789][0123456789][0123456789].host.com) echo "Backup server" ;;
  *) echo "Unknown server" ;;
esac

但这对超过999台服务器不起作用。

如果我必须为这个用例编写一个脚本,我可能会编写类似的东西(因为我喜欢正则表达式和case语法;)):

srv=`expr "$SERVER" : '^\(db\|bk\|ws\)-[0-9]\+\.host\.com$'`
echo -n "$SERVER : "
case $srv in
  ws) echo "Web Server" ;;
  db) echo "DB server" ;;
  bk) echo "Backup server" ;;
  *) echo "Unknown server !!!"
esac

答案 3 :(得分:4)

您也可以使用expr进行匹配;它提供了类似grep的正则表达式语法,该语法对于此应用程序应该足够健壮。

#!/bin/bash

server=$1
if   expr "$server" : 'ws-[0-9]\+\.host\.com' >/dev/null; then echo "Web server"
elif expr "$server" : 'db-[0-9]\+\.host\.com' >/dev/null; then echo "DB server"
elif expr "$server" : 'bk-[0-9]\+\.host\.com' >/dev/null; then echo "Backup server"
else echo "Unknown server"
fi

答案 4 :(得分:4)

以下是如何使用elif构造的示例。

#!/bin/bash
SERVER=$1;
regex_ws="^ws-[0-9]+\.host\.com$"
regex_db="^db-[0-9]+\.host\.com$"
regex_bk="^bk-[0-9]+\.host\.com$"
if [[ "${SERVER}" =~ $regex_ws ]]; then
  echo "Web Server"
elif [[ "${SERVER}" =~ $regex_db ]]; then
  echo "DB server"
elif [[ "${SERVER}" =~ $regex_bk ]]; then
  echo "Backup server"
else
  echo "Unknown server"
fi

我认为将正则表达式存储在自己的变量中是最可靠的。

答案 5 :(得分:0)

我知道这是一个相当老的问题,我的解决方案与@syjust所提供的解决方案并没有太大不同,但我想证明您可以在{{ 1}}语句。

case/esac

答案 6 :(得分:0)

作为参考,但是在man bash的{​​{3}}中已经提到了这一点,“模式匹配”部分提供了用于创建复合模式的规则,如下所示:

可以使用以下一个或多个子图案来形成复合图案:

?(模式列表)
匹配零个或一次出现的给定模式。
*(模式列表)
匹配零个或多个给定模式的出现。
+(模式列表)
匹配给定模式的一个或多个出现。
@(模式列表)
匹配给定的模式之一。
!(模式列表)
匹配给定模式之一以外的任何内容。

但是,使用这些扩展模式匹配要求启用extglob shell选项。

以下是当前问题的代码示例:

shopt -s extglob;
SERVER="ws-45454.host.com";
case $SERVER in
        ws-+([0-9])\.host\.com) echo "Web Server"
                ;;
        db-+([0-9])\.host\.com) echo "DB server"
                ;;
        bk-+([0-9])\.host\.com) echo "Backup server"
                ;;
        *)echo "Unknown server"
                ;;
esac;
shopt -u extglob;

此外,此shopt | grep extglob可用于检查其默认值。