Mam dane wyjściowe, z VBoxManage list vmsktórych wygląda to tak:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Muszę złapać nazwy archi arch2i zapisać je w zmiennej.
Mam dane wyjściowe, z VBoxManage list vmsktórych wygląda to tak:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Muszę złapać nazwy archi arch2i zapisać je w zmiennej.
Odpowiedzi:
Spowoduje to przeanalizowanie zawartości tych 2 ciągów:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
Powyższe wygląda na ciąg pasujący do wzoru ".*". To pasuje do wszystkiego, co występuje w obrębie podwójnych cudzysłowów. Więc grepzwrócą te typy wartości:
"arch"
"arch2"
Rura do sedusunie wszelkie podwójne cudzysłowy z tych ciągów, dając ciągi, których szukasz. Zapis sed 's/"//g'jest instruowanie sedzrobić wyszukiwania i zamiany na wszystkie wystąpienia cudzysłowach, zastępując je z niczego s/"//g. Polecenie s/find/replace/gjest tym, co się tam dzieje, a gciąg wyszukiwania służy do tego, aby zrobić to globalnie na całym podanym ciągu.
Możesz także użyć seddo odcięcia początkowego podwójnego cytatu, zatrzymania tego, co jest między nimi, i odcięcia pozostałego cytatu + wszystkiego po nim:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
Polecenia trmożna używać do usuwania znaków. W tym przypadku usuwa podwójne cudzysłowy.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Korzystając grepz funkcji PCRE możesz wyszukać dowolne podciągi, które zaczynają się od podwójnego cudzysłowu lub kończą podwójnym cudzysłowiem i zgłaszają tylko podłańcuchy.
/address/do sedjak sed '/^"\(arch[^"]*\)/s//\1/będziesz pracować wyłącznie na liniach zawierających ten ciąg.
sednaprawdę powinieneś robić s/^"\([^"]*\)".*/\1/na wypadek, gdyby na linii były tylko dwa podwójne cudzysłowy.
To kolejna praca dla cut:
VBoxManage list vms | cut -d \" -f2
cutdzieli każdą linię na pola przy użyciu znaku cudzysłowu jako separatora, a następnie wypisuje pole 2: pole 1 jest pustym ciągiem przed pierwszym cytatem, pole 2 jest poszukiwanym ciągiem między cytatami, a pole 3 jest resztą linia.
Dzięki sedniemu możesz:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Wyjaśnienie:
s/.../.../ - dopasuj i zamień^- mecz na początku linii\(...\) - jest to odniesienie wstecz, możemy odwołać się do tego, co jest tutaj dopasowane później \1[^"]*- dopasuj dowolną sekwencję, która nie zawiera "(tj. do następnej ").* - dopasuj do reszty linii\1 - zastąpić referencją wstecznąLub z awk:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Zauważ, że we współczesnych powłokach możesz także użyć tablicy zamiast normalnej zmiennej. W bashmożna zrobić:
IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"
To może być łatwiejsze, gdy przychodzi się do użycia zmiennej.
Używając bash, napisałbym:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2
I ten przez grep oneliner z --perl-regexpopcją,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Wyjaśnienie:
(?<=^\")[^"]*-> Tutaj jest używany wygląd. Dopasowuje dowolny znak, ale nie "zero lub więcej razy (gdy znajdzie podwójne cudzysłowy, przestaje się dopasowywać), które są tuż po podwójnych cudzysłowach (tylko wiersz zaczynający się od podwójnych cudzysłowów).
Kolejny brzydki włam sed,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
ponieważ regex ma tryby chciwości i chciwości, jeśli masz wiele celów w tej samej linii, nie wyodrębni się tak, jak chcesz. Linia:
"tom" is a cat, and "jerry" is a mouse.
Cel:
tom
jerry
Polecenie (tryb zachłanny):
grep -oP '".*"' name
Polecenie (tryb bez chciwości):
grep -oP '".*?"' name
tr -d \"to kolejny sposób na usunięcie cytatów. (trzwykle tłumaczy jeden zestaw znaków na inny;-dkaże mu je po prostu usunąć).