
Eu tenho uma saída VBoxManage list vms
que se parece com esta:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Preciso pegar os nomes arch
e arch2
salvá-los em uma variável.
Responder1
Usando grep + sed
Isso analisará o conteúdo dessas 2 strings:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
O acima procura uma string que corresponda ao padrão ".*"
. Isso corresponderá a tudo o que ocorrer entre aspas duplas. Então grep
retornará estes tipos de valores:
"arch"
"arch2"
O pipe to sed
removerá as aspas duplas dessas strings, fornecendo as strings que você está procurando. A notação sed 's/"//g'
instrui sed
a fazer uma pesquisa e substituir todas as ocorrências de aspas duplas, substituindo-as por nada, s/"//g
. O comando s/find/replace/g
é o que está acontecendo lá, e o final g
da pesquisa diz para fazer isso globalmente em toda a string fornecida.
Usando apenas sed
Você também pode usar sed
para cortar as aspas duplas iniciais, manter o que está entre elas e cortar as aspas restantes + tudo o que vem depois:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
Outros métodos
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
O comando tr
pode ser usado para excluir caracteres. Neste caso, está excluindo as aspas duplas.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Usando grep
o recurso PCRE de ', você pode procurar qualquer substring que comece com aspas duplas ou termine com aspas duplas e relatar apenas a substring.
Responder2
Esse é outro trabalho para cut
:
VBoxManage list vms | cut -d \" -f2
Responder3
Com sed
você você pode fazer:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Explicação:
s/.../.../
- combinar e substituir^
- partida no início da linha\(...\)
- esta é uma referência anterior, podemos nos referir ao que corresponde aqui mais tarde com\1
[^"]*
- corresponde a qualquer sequência que não contenha a"
(ou seja, até a próxima"
).*
- combine o resto da linha\1
- substitua pela referência anterior
Ou com awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Observe que em shells modernos você também pode usar um array em vez de uma variável normal. Em bash
você pode fazer:
IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"
Isso pode ser mais fácil quando você usar a variável.
Responder4
Usando o bash, eu escreveria:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2