Регулярные выражения в выражении Bash case - PullRequest
31 голосов
/ 09 марта 2012

Я использую следующий скрипт, который использует оператор 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

Но это не работает. Regex работает с egrep, но не с case. образец O / P

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

Есть идеи?

Ответы [ 6 ]

39 голосов
/ 09 марта 2012

Bash case не использует регулярные выражения, но соответствует шаблону оболочки только .

Поэтому вместо регулярного выражения ws-[0-9]+\.host\.com вы должны использовать шаблон ws*.host.com (или ws-+([0-9]).host.com, но это выглядит немного сложнее, и я никогда не пробовал это: -)

9 голосов
/ 09 марта 2012

case можно использовать только шарики.Если вы хотите выполнить сопоставление с регулярным выражением, вам нужно использовать серию if-then-else-elif-fi операторов, с [[.

8 голосов
/ 12 сентября 2014

Если вы хотите подтвердить, что * действительно соответствует цифрам в ws*.host.com и хотите использовать case вместо 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

Но это не работает для более чем 999 серверов.

Если бы мне пришлось создать сценарий для этого варианта использования, я, вероятно, написал бы что-то подобное (потому что я люблю регулярные выражения и синтаксис регистра;)):

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
4 голосов
/ 19 июня 2017

Вот пример использования конструкции 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

Я считаю наиболее надежным хранить регулярные выражения в их собственных переменных.

4 голосов
/ 26 августа 2014

Вы также можете использовать 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
1 голос
/ 31 мая 2019

Я знаю, что это довольно старый вопрос, и мое решение мало чем отличается от того, что уже предоставил @ syjust , но я хотел показать, что вы можете делать практически все на этапе сопоставления case/esac заявление.

$ cat case.sh && echo -e "#################\n" && bash case.sh ws-23.host.com
#!/bin/bash
SERVER=$1;
echo $SERVER | egrep "ws-[0-9]+\.host\.com";
case $SERVER in
  $(awk '{a=0}/ws-[0-9]*.host.com/{a=1}a' <<<${SERVER}))echo "Web Server";;
  $(awk '{a=0}/db-[0-9]*.host.com/{a=1}a' <<<${SERVER}))echo "DB Server";;
  $(awk '{a=0}/bk-[0-9]*.host.com/{a=1}a' <<<${SERVER}))echo "Backup Server";;
  *)echo "Unknown server";;
esac

#################

ws-23.host.com
Web Server

...