Ich habe eine Ausgabe, VBoxManage list vms
die so aussieht:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Ich brauche die Namen zu greifen arch
und arch2
und sie in eine Variable speichern.
Ich habe eine Ausgabe, VBoxManage list vms
die so aussieht:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Ich brauche die Namen zu greifen arch
und arch2
und sie in eine Variable speichern.
Antworten:
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 passt zu allem, was in doppelten Anführungszeichen steht. So grep
werden diese Arten von Werten zurückgegeben:
"arch"
"arch2"
Die Pipe zum sed
Entfernen von doppelten Anführungszeichen aus diesen Zeichenfolgen gibt Ihnen die Zeichenfolgen, nach denen Sie suchen. In der Notation sed 's/"//g'
wird angewiesen sed
, alle doppelten Anführungszeichen zu suchen und durch nichts zu ersetzen s/"//g
. Der Befehl s/find/replace/g
ist das, was dort vor sich geht, und der g
Suchpfad weist ihn an, dies global für die gesamte angegebene Zeichenfolge zu tun.
Sie können auch verwenden sed
, um das anfängliche doppelte Anführungszeichen abzuschneiden, den Abstand zwischen ihnen beizubehalten und das verbleibende Anführungszeichen abzubrechen.
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
Mit dem Befehl tr
können Zeichen gelöscht werden. In diesem Fall werden die doppelten Anführungszeichen gelöscht.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Mit grep
der PCRE-Funktion von können Sie nach Unterzeichenfolgen suchen, die mit einem doppelten Anführungszeichen beginnen oder mit einem doppelten Anführungszeichen enden, und nur die Unterzeichenfolge melden.
/address/
to sed
like hinzufügen , können sed '/^"\(arch[^"]*\)/s//\1/
Sie nur Zeilen bearbeiten , die diesen String enthalten.
sed
wirklich tun sollten, s/^"\([^"]*\)".*/\1/
nur für den Fall, dass nur zwei doppelte Anführungszeichen in der Zeile stehen.
Das ist ein weiterer Job für cut
:
VBoxManage list vms | cut -d \" -f2
cut
Teilt jede Zeile in Felder unter Verwendung des Anführungszeichens als Trennzeichen und gibt dann Feld 2 aus: Feld 1 ist die leere Zeichenfolge vor dem ersten Anführungszeichen, Feld 2 ist die gewünschte Zeichenfolge zwischen den Anführungszeichen und Feld 3 ist der Rest der Linie.
Mit sed
können Sie:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Erläuterung:
s/.../.../
- anpassen und ersetzen^
- Spiel am Zeilenanfang\(...\)
- Dies ist eine Rückreferenz, wir können auf das verweisen, was hier später mit übereinstimmt \1
[^"]*
- Übereinstimmung mit einer Sequenz, die kein a enthält "
(dh bis zur nächsten)"
).*
- Passen Sie den Rest der Linie an\1
- durch die rückseitige Referenz ersetzenOder mit awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Beachten Sie, dass Sie in modernen Shells anstelle einer normalen Variablen auch ein Array verwenden können. In können bash
Sie 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.
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
Und die durch Grep Oneliner mit --perl-regexp
Option,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Erläuterung:
(?<=^\")[^"]*
-> Hier wird ein Lookbehind verwendet. Es stimmt mit jedem Zeichen überein, jedoch nicht mit "
null oder mehreren Übereinstimmungen (sobald es doppelte Anführungszeichen findet, hört es auf, übereinzustimmen), die direkt nach doppelten Anführungszeichen stehen (nur die Zeile, die mit doppelten Anführungszeichen beginnt).
Ein weiterer hässlicher Hack durch sed
,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
Da Regex gierige und nicht gierige Modi hat, würde es nicht wie gewünscht extrahiert, wenn Sie mehrere Ziele in derselben Zeile haben. Linie:
"tom" is a cat, and "jerry" is a mouse.
Ziel:
tom
jerry
Befehl (gieriger Modus):
grep -oP '".*"' name
Befehl (nicht gieriger Modus):
grep -oP '".*?"' name
tr -d \"
ist eine andere Möglichkeit, die Anführungszeichen zu löschen. (tr
Übersetzt normalerweise einen Zeichensatz in einen anderen;-d