1101 Stimmen

Wie kann ich in Bash prüfen, ob eine Zeichenfolge mit einem Wert beginnt?

Ich möchte prüfen, ob eine Zeichenfolge mit "node" beginnt, z. B. "node001". Etwas wie

if [ $HOST == user* ]
  then
  echo yes
fi

Wie kann ich es richtig machen?


Ich muss außerdem Ausdrücke kombinieren, um zu prüfen, ob HOST entweder "user1" ist oder mit "node" beginnt

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi

> > > -bash: [: too many arguments

Wie kann ich es richtig machen?

45voto

dhke Punkte 14388

Ich finde zwar die meisten Antworten richtig, aber viele von ihnen enthalten unnötige Bashismen. POSIX-Parameter-Erweiterung gibt Ihnen alles, was Sie brauchen:

[ "${host#user}" != "${host}" ]

et

[ "${host#node}" != "${host}" ]

${var#expr} entfernt das kleinste Präfix, das mit expr de ${var} und gibt diese zurück. Wenn also ${host} tut pas beginnen mit user ( node ), ${host#user} ( ${host#node} ) ist dasselbe wie ${host} .

expr ermöglicht fnmatch() Wildcards, also ${host#node??} und Freunde arbeiten auch.

39voto

ozma Punkte 1493

Seit # in Bash eine Bedeutung hat, bin ich zu folgender Lösung gekommen.

Außerdem packe ich Zeichenketten lieber mit "", um Leerzeichen usw. zu vermeiden.

A="#sdfs"
if [[ "$A" == "#"* ]];then
    echo "Skip comment line"
fi

16voto

MrPotatoHead Punkte 721

Ein kleines bisschen mehr Syntax-Detail zu Mark Rushakoffs höchstrangiger Antwort.

Der Ausdruck

$HOST == node*

Kann auch geschrieben werden als

$HOST == "node"*

Die Wirkung ist dieselbe. Achten Sie nur darauf, dass der Platzhalter außerhalb des zitierten Textes steht. Wenn der Platzhalter dentro de die Anführungszeichen, wird es wörtlich interpretiert (d.h. nicht als Platzhalter).

8voto

ghostdog74 Punkte 305138

@OP, für Ihre beiden Fragen können Sie case/esac verwenden:

string="node001"
case "$string" in
  node*) echo "found";;
  * ) echo "no node";;
esac

Zweite Frage

case "$HOST" in
 node*) echo "ok";;
 user) echo "ok";;
esac

case "$HOST" in
 node*|user) echo "ok";;
esac

Oder Bash 4.0

case "$HOST" in
 user) ;&
 node*) echo "ok";;
esac

6voto

just somebody Punkte 17584
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi

funktioniert nicht, weil alle [ , [[ そして test die gleiche nicht-rekursive Grammatik erkennen. Siehe Abschnitt BEDINGTE AUSDRÜCKE auf Ihrer Bash-Manpage.

Nebenbei bemerkt, sagt die SUSv3

Der von der KornShell abgeleitete bedingte Befehl (doppelte Klammer [[]] ) wurde in einem frühen Vorschlag aus der Beschreibung der Shell-Befehlssprache entfernt. Es wurde eingewandt, dass das eigentliche Problem der Missbrauch der Test Befehl ( [ ), und es in die Shell einzubauen ist der falsche Weg, das Problem zu lösen. Stattdessen sollten eine ordentliche Dokumentation und ein neues für die Shell reserviertes Wort ( ! ) sind ausreichend.

Tests, die eine Vielzahl von Test Operationen können auf der Shell-Ebene mit einzelnen Aufrufen des Befehls Test Befehl und Shell-Logicals zu verwenden, anstatt die fehleranfällige -o Flagge von Test .

Sie müssten es so schreiben, aber Test unterstützt es nicht:

if [ $HOST == user1 -o $HOST == node* ];
then
echo yes
fi

Test verwendet \= für die Gleichheit von Zeichenketten, und, was noch wichtiger ist, es unterstützt keinen Mustervergleich.

case / esac bietet eine gute Unterstützung für den Mustervergleich:

case $HOST in
user1|node*) echo yes ;;
esac

Es hat den zusätzlichen Vorteil, dass es nicht von der Bash abhängt und die Syntax portabel ist. Von der _Einzelne Unix-Spezifikation_ , Die Shell-Befehlssprache :

case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X