bash: Wie verwende ich mehrere String-Manipulationen (Parametererweiterung) in einem Schritt?

Aug 15 2020

Ich habe, string=substr1-substr2-substr3.substr4wo die Teilzeichenfolgen von variabler Länge sind. Ich möchte substr3aus stringden Erweiterungen ${string##pattern}und der ${string%pattern}String-Manipulation extrahieren und denke darüber nach, dies zu tun . Mit diesem Ansatz ist klar, dass ich die resultierende Erweiterung ${string##*-}ausführen ${string%.*}muss oder umgekehrt oder umgekehrt. Meine Fragen sind:

  1. ist das die beste Wahl?
  2. Wenn ja, wie führe ich beide in einem Schritt aus? Wenn ich versuche, so etwas zu tun, ${string##*-${string%.*}}oder ${string%.*${string##*-}}wenn ich nur die volle Zeichenfolge zurück bekomme. Mir ist klar, dass ich die Extraktion immer in zwei Schritten durchführen kann, indem ich dem Ergebnis des ersten Schritts eine Zwischenvariable zuweise und diese dann manipuliere. aber ich möchte es in einem Schritt tun. Wie gehe ich vor?

TIA!

Antworten

2 ilkkachu Aug 15 2020 at 20:39

Gegeben

string=substr1-substr2-substr3.substr4

${string%.*} ist

substr1-substr2-substr3

so ${string##*-${string%.*}}ist

${string##*-substr1-substr2-substr3}

was bedeutet, von Anfang an stringalles bis einschließlich zu entfernen -substr1-substr2-substr3. Aber es gibt keinen solchen Teilstring string, da kein Strich davor ist substr1, sodass Sie den Originalstring erhalten.

Was Sie wahrscheinlich wollen, ist

string=substr1-substr2-substr3.substr4
result="${string%.*}" result="${result##*-}"

was zu resultcontaing führt substr3.

In Zsh können Sie dies in einem Schritt tun: Aber das funktioniert in Bash nicht.result=${${string%.*}##*-}

In Bash können Sie nur Erweiterungen auf der rechten Seite von #oder verwenden. Dies %hilft Ihnen hier nicht weiter, da Sie Teile sowohl am Anfang als auch am Ende der Zeichenfolge entfernen müssen.


Alternativ können Sie verwenden, wenn $stringkeine Zeilenumbrüche enthalten sind

IFS=.- read -r a b c d <<< "$string"

und ablesen substr3von c.

In diesem Fall wird der Inhalt von abhängig von der Shell und der Größe der Zeichenfolge $stringentweder in einer temporären Datei gespeichert oder durch eine Pipe geleitet, die readdie erste Zeile aus liest und entsprechend aufteilt $IFS.