Bash case语句中的正则表达式

时间:2023-01-08 15:45:53

I am using following script, which uses case statement to find the server.

我正在使用下面的脚本,它使用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

But it is not working. Regex is working with egrep but not with case. sample O/P

但这并不奏效。Regex正在与白鹭一起工作,但不是用例。样本O / P

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

Any Idea ?

任何想法?

5 个解决方案

#1


34  

Bash case does not use regular expressions, but shell pattern matching only.

Bash case不使用正则表达式,而只使用shell模式匹配。

Therefore, instead of regex ws-[0-9]+\.host\.com you should use pattern ws*.host.com (or ws-+([0-9]).host.com, but that looks a bit advanced and I've never tried that :-)

因此,您应该使用模式ws*.host.com(或ws-+([0-9]).host.com,而不是regex ws-[0-9]+\。

#2


8  

If you want assert that * really matches digits in ws*.host.com and want to use case instead of if, elif, elif... you can use something like that:

如果您想要断言*在ws*.host.com中确实匹配数字,并且希望用例而不是If, elif, elif…你可以这样使用:

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

But that does not work for more than 999 servers.

但这对于999个服务器来说是行不通的。

If I had to make a script for this use case, I probably write something like that (because I love regexes and case syntax ;) ):

如果我必须为这个用例编写一个脚本,我可能会这样写(因为我喜欢regexes和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


5  

case can only use globs. If you want to do regex matching then you'll need to use a series of if-then-else-elif-fi statements, with [[.

case只能使用globs。如果要进行regex匹配,则需要使用一系列If -then-else-elif-fi语句,并使用[]。

#4


3  

You can also use expr to do the matching; it provides a grep-like regular expression syntax that should be robust enough for this application.

也可以使用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

#5


2  

Here’s an example of how to use the elif construct.

这里有一个如何使用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

I find it most reliable to store the regular expressions in their own variables.

我发现将正则表达式存储在它们自己的变量中是最可靠的。

#1


34  

Bash case does not use regular expressions, but shell pattern matching only.

Bash case不使用正则表达式,而只使用shell模式匹配。

Therefore, instead of regex ws-[0-9]+\.host\.com you should use pattern ws*.host.com (or ws-+([0-9]).host.com, but that looks a bit advanced and I've never tried that :-)

因此,您应该使用模式ws*.host.com(或ws-+([0-9]).host.com,而不是regex ws-[0-9]+\。

#2


8  

If you want assert that * really matches digits in ws*.host.com and want to use case instead of if, elif, elif... you can use something like that:

如果您想要断言*在ws*.host.com中确实匹配数字,并且希望用例而不是If, elif, elif…你可以这样使用:

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

But that does not work for more than 999 servers.

但这对于999个服务器来说是行不通的。

If I had to make a script for this use case, I probably write something like that (because I love regexes and case syntax ;) ):

如果我必须为这个用例编写一个脚本,我可能会这样写(因为我喜欢regexes和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


5  

case can only use globs. If you want to do regex matching then you'll need to use a series of if-then-else-elif-fi statements, with [[.

case只能使用globs。如果要进行regex匹配,则需要使用一系列If -then-else-elif-fi语句,并使用[]。

#4


3  

You can also use expr to do the matching; it provides a grep-like regular expression syntax that should be robust enough for this application.

也可以使用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

#5


2  

Here’s an example of how to use the elif construct.

这里有一个如何使用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

I find it most reliable to store the regular expressions in their own variables.

我发现将正则表达式存储在它们自己的变量中是最可靠的。