¿Cómo extraigo el contenido de las cadenas entre comillas del resultado de un comando?

¿Cómo extraigo el contenido de las cadenas entre comillas del resultado de un comando?

Tengo un resultado VBoxManage list vmsque se parece a este:

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

Necesito tomar los nombres archy arch2guardarlos en una variable.

Respuesta1

Usando grep + sed

Esto analizará el contenido de esas 2 cadenas:

$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2

Lo anterior busca una cadena que coincida con el patrón ".*". Eso coincidirá con todo lo que ocurra entre comillas dobles. Entonces grepdevolverá este tipo de valores:

"arch"
"arch2"

La tubería sedeliminará las comillas dobles de estas cadenas, dándole las cadenas que está buscando. La notación sed 's/"//g'indica que sedse debe realizar una búsqueda y reemplazar todas las apariciones de comillas dobles, reemplazándolas por nada s/"//g. El comando s/find/replace/ges lo que sucede allí, y el final gde la búsqueda le indica que lo haga globalmente en toda la cadena que se le proporciona.

Usando solo sed

También puedes usar sedpara cortar la comilla doble inicial, conservar lo que hay entre ellas y cortar la comilla restante + todo lo que sigue después:

$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2

Otros metodos

$ grep -o '".*"' somefile | tr -d '"'
arch
arch2

El comando trse puede utilizar para eliminar caracteres. En este caso se trata de eliminar las comillas dobles.

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

Con grepla función PCRE de 's, puede buscar cualquier subcadena que comience con una comilla doble o termine con una comilla doble e informar solo la subcadena.

Respuesta2

Ese es otro trabajo para cut:

VBoxManage list vms | cut -d \" -f2

Respuesta3

Con sedpuedes hacer:

var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')

Explicación:

  • s/.../.../- emparejar y reemplazar
  • ^- coincidir al inicio de la línea
  • \(...\)- esta es una referencia anterior, podemos referirnos a lo que coincide aquí más adelante con\1
  • [^"]*- haga coincidir cualquier secuencia que no contenga un "(es decir, hasta el siguiente ")
  • .*- coincide con el resto de la línea
  • \1- reemplazar con la referencia anterior

O con awk:

var=$(VBoxManage list vms | awk -F\" '{ print $2 }')

Tenga en cuenta que en los shells modernos también puede utilizar una matriz en lugar de una variable normal. En bashpuedes hacer:

IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"

Esto podría ser más fácil cuando empiece a utilizar la variable.

Respuesta4

Usando bash, escribiría:

while read vm value; do
    case $vm in
        '"arch"') arch=$value ;;
        '"arch2"') arch2=$value ;;
    esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2

información relacionada