Wie extrahiere ich den Inhalt von in Anführungszeichen gesetzten Zeichenfolgen aus der Ausgabe eines Befehls?

Wie extrahiere ich den Inhalt von in Anführungszeichen gesetzten Zeichenfolgen aus der Ausgabe eines Befehls?

Ich habe eine Ausgabe, VBoxManage list vmsdie so aussieht:

"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}   
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}  

Ich muss die Namen erfassen archund arch2in einer Variablen speichern.

Antwort1

Verwenden von grep + sed

Dadurch wird der Inhalt dieser beiden Zeichenfolgen analysiert:

$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2

Oben wird nach einer Zeichenfolge gesucht, die dem Muster entspricht ".*". Das entspricht allem, was in Anführungszeichen steht. Daher grepwerden folgende Wertetypen zurückgegeben:

"arch"
"arch2"

Die Pipe to sedentfernt alle doppelten Anführungszeichen aus diesen Zeichenfolgen und gibt Ihnen die Zeichenfolgen, nach denen Sie suchen. Die Notation sed 's/"//g'weist an, sedalle Vorkommen von doppelten Anführungszeichen zu suchen und zu ersetzen und sie durch nichts zu ersetzen s/"//g. Der Befehl s/find/replace/gist das, was hier passiert, und das nachfolgende gto search weist ihn an, dies global für die gesamte angegebene Zeichenfolge durchzuführen.

Nur sed verwenden

Sie können auch verwenden, sedum die Anführungszeichen am Anfang abzuschneiden, den Inhalt dazwischen beizubehalten und das verbleibende Anführungszeichen sowie alles, was danach kommt, abzuschneiden:

$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2

Andere Methoden

$ grep -o '".*"' somefile | tr -d '"'
arch
arch2

Mit dem Befehl trkönnen Zeichen gelöscht werden. In diesem Fall werden die Anführungszeichen gelöscht.

$ grep -oP '(?<=").*(?=")' somefile
arch
arch2

Mit grepder PCRE-Funktion können Sie nach allen Teilzeichenfolgen suchen, die mit einem doppelten Anführungszeichen beginnen oder enden, und nur die Teilzeichenfolge melden.

Antwort2

Das ist ein weiterer Job für cut:

VBoxManage list vms | cut -d \" -f2

Antwort3

Mit sedkönnen Sie:

var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')

Erläuterung:

  • s/.../.../- Abgleichen und Ersetzen
  • ^- Übereinstimmung am Zeilenanfang
  • \(...\)- dies ist eine Rückverweis, wir können später auf das verweisen, was hier übereinstimmt mit\1
  • [^"]*- passt zu jeder Sequenz, die kein enthält "(also bis zum nächsten ")
  • .*- mit dem Rest der Zeile übereinstimmen
  • \1- durch die Rückreferenz ersetzen

Oder mit awk:

var=$(VBoxManage list vms | awk -F\" '{ print $2 }')

Beachten Sie, dass Sie in modernen Shells anstelle einer normalen Variable auch ein Array verwenden können. bashSie können Folgendes tun:

IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"

Dies ist möglicherweise einfacher, wenn Sie die Variable verwenden.

Antwort4

Mit Bash würde ich schreiben:

while read vm value; do
    case $vm in
        '"arch"') arch=$value ;;
        '"arch2"') arch2=$value ;;
    esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2

verwandte Informationen