Como extraio o conteúdo das strings citadas da saída de um comando?

Como extraio o conteúdo das strings citadas da saída de um comando?

Eu tenho uma saída VBoxManage list vmsque se parece com esta:

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

Preciso pegar os nomes arche arch2salvá-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 grepretornará estes tipos de valores:

"arch"
"arch2"

O pipe to sedremoverá as aspas duplas dessas strings, fornecendo as strings que você está procurando. A notação sed 's/"//g'instrui seda 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 gda pesquisa diz para fazer isso globalmente em toda a string fornecida.

Usando apenas sed

Você também pode usar sedpara 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 trpode ser usado para excluir caracteres. Neste caso, está excluindo as aspas duplas.

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

Usando grepo 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 sedvocê 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 bashvocê 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

informação relacionada