webentwicklung-frage-antwort-db.com.de

Reguläre Ausdrücke in einer Bash-Case-Anweisung

Ich verwende das folgende Skript, das case-Anweisung verwendet, um den Server zu finden.

    #!/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

Aber es funktioniert nicht. Regex arbeitet mit egrep, aber nicht mit case. Probe O/P

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

Irgendeine Idee ?

36
Unni

In der Bash-Schreibweise werden keine regulären Ausdrücke verwendet, sondern nur Shell Pattern Matching .

Daher solltest du anstelle von regex ws-[0-9]+\.Host\.com Das Muster ws*.Host.com (Oder ws-+([0-9]).Host.com verwenden, aber das sieht ein bisschen fortgeschritten aus und das habe ich noch nie ausprobiert :-)

44
che

case kann nur Globs verwenden. Wenn Sie einen Regex-Abgleich durchführen möchten, müssen Sie eine Reihe von if-then-else-Elif-fi Aussagen, mit [[.

Wenn Sie behaupten möchten, dass * Wirklich mit den Ziffern in ws*.Host.com Übereinstimmt, und case anstelle von if, Elif, Elif... du kannst so etwas benutzen:

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

Dies funktioniert jedoch nicht für mehr als 999 Server.

Wenn ich ein Skript für diesen Anwendungsfall erstellen müsste, würde ich wahrscheinlich so etwas schreiben (weil ich Regexes und Case-Syntax liebe;)):

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
9
syjust

Hier ist ein Beispiel für die Verwendung des Elif -Konstrukts.

#!/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

Ich finde es am zuverlässigsten, die regulären Ausdrücke in ihren eigenen Variablen zu speichern.

5
mlowry

Sie können auch expr verwenden, um den Abgleich durchzuführen. Es bietet eine grep-ähnliche Syntax für reguläre Ausdrücke, die für diese Anwendung robust genug sein sollte.

#!/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
tkocmathla

Ich weiß, dass dies eine ziemlich alte Frage ist und meine Lösung sich nicht wesentlich von der unterscheidet, die @ syjust bereits geliefert hat, aber ich wollte zeigen, dass Sie in einer case/esac Anweisung.

$ 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

1
AnthonyK