Ho un output dal VBoxManage list vms
quale assomiglia a questo:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Ho bisogno di prendere i nomi arch
e arch2
e salvarli in una variabile.
Ho un output dal VBoxManage list vms
quale assomiglia a questo:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Ho bisogno di prendere i nomi arch
e arch2
e salvarli in una variabile.
Risposte:
Questo analizzerà il contenuto di quelle 2 stringhe:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
Quanto sopra cerca una stringa che corrisponda al modello ".*"
. Che corrisponderà a tutto ciò che accade tra virgolette doppie. Quindi grep
restituirà questi tipi di valori:
"arch"
"arch2"
La pipe per sed
rimuovere tutte le doppie virgolette da queste stringhe dando le stringhe che stai cercando. La notazione sed 's/"//g'
indica sed
di fare una ricerca e di sostituire tutte le occorrenze di virgolette doppie, sostituendole con nulla s/"//g
. Il comando s/find/replace/g
è quello che sta succedendo lì, e il trailing g
da cercare gli dice di farlo globalmente sull'intera stringa che gli viene data.
Puoi anche usare sed
per tagliare la doppia citazione iniziale, mantenere ciò che c'è tra loro e tagliare la citazione rimanente + tutto ciò che segue:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
Il comando tr
può essere utilizzato per eliminare caratteri. In questo caso sta eliminando le doppie virgolette.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Usando grep
la funzione PCRE puoi cercare tutte le sottostringhe che iniziano con una doppia citazione o terminano con una doppia citazione e riportano solo la sottostringa.
/address/
per sed
come sed '/^"\(arch[^"]*\)/s//\1/
potrai operare solo sulle linee che contengono quella stringa.
sed
dovresti davvero farlo s/^"\([^"]*\)".*/\1/
nel caso in cui ci siano solo due doppie virgolette sulla riga.
Questo è un altro lavoro per cut
:
VBoxManage list vms | cut -d \" -f2
cut
suddivide ogni riga in campi usando il segno di virgolette come delimitatore, quindi genera il campo 2: il campo 1 è la stringa vuota prima della prima citazione, il campo 2 è la stringa desiderata tra le virgolette e il campo 3 è il resto del linea.
Con sed
te puoi fare:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Spiegazione:
s/.../.../
- abbina e sostituisci^
- partita all'inizio della riga\(...\)
- questo è un riferimento indietro, possiamo fare riferimento a ciò che verrà abbinato qui in seguito con \1
[^"]*
- corrisponde a qualsiasi sequenza che non contiene un "
(cioè fino alla successiva "
).*
- abbina il resto della linea\1
- sostituire con il riferimento posterioreO con awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Nota che nelle shell moderne puoi anche usare un array invece di una normale variabile. In bash
puoi fare:
IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"
Questo potrebbe essere più semplice quando si utilizza la variabile.
Usando bash, scriverei:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2
E quello attraverso grep oneliner con --perl-regexp
opzione,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Spiegazione:
(?<=^\")[^"]*
-> Qui viene utilizzato un lookbehind. "
Corrisponde a qualsiasi carattere ma non di zero o più volte (una volta trovata una virgoletta doppia, interrompe la corrispondenza) che sono subito dopo le virgolette doppie (solo la riga che inizia con le virgolette doppie).
Un altro brutto hack sed
,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
tr -d \"
è un altro modo per eliminare le virgolette. (ditr
solito traduce un set di caratteri in un altro;-d
dice invece di eliminarli invece.)