Tengo salida de VBoxManage list vms
que se ve así:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Tengo que agarrar los nombres arch
y arch2
y guardarlos en una variable.
Tengo salida de VBoxManage list vms
que se ve así:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Tengo que agarrar los nombres arch
y arch2
y guardarlos en una variable.
Respuestas:
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 cualquier cosa que ocurra entre comillas dobles. Entonces grep
devolverá este tipo de valores:
"arch"
"arch2"
La canalización sed
eliminará las comillas dobles de estas cadenas para darle las cadenas que está buscando. La notación sed 's/"//g'
está instruyendo a sed
hacer una búsqueda y reemplazo en todas las apariciones de comillas dobles, sustituyéndolas con nada, s/"//g
. El comando s/find/replace/g
es lo que está sucediendo allí, y el seguimiento g
de la búsqueda le dice que lo haga globalmente en toda la cadena que se le da.
También puede usar sed
para cortar la comilla doble inicial, mantener lo que hay entre ellas y cortar la comilla restante + todo lo que está después:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
El comando tr
se puede usar para eliminar caracteres. En este caso, se eliminan las comillas dobles.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
Con grep
la función PCRE, puede buscar cualquier subcadena que comience con una comilla doble o termine con una comilla doble e informe solo la subcadena.
/address/
al sed
igual que sed '/^"\(arch[^"]*\)/s//\1/
usted sólo opera en las líneas que contienen esa cadena.
sed
realmente debería hacerlo s/^"\([^"]*\)".*/\1/
solo en caso de que solo haya dos comillas dobles en la línea.
Ese es otro trabajo para cut
:
VBoxManage list vms | cut -d \" -f2
cut
divide cada línea en campos usando la comilla como delimitador, luego genera el campo 2: el campo 1 es la cadena vacía antes de la primera cita, el campo 2 es la cadena deseada entre las comillas y el campo 3 es el resto del línea.
Con sed
usted puede hacer:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Explicación:
s/.../.../
- emparejar y reemplazar^
- partido al inicio de la línea\(...\)
- esta es una referencia inversa, podemos referirnos a lo que coincide aquí más adelante con \1
[^"]*
- coincide con cualquier secuencia que no contenga un "
(es decir, hasta el siguiente "
).*
- coincide con el resto de la línea\1
- reemplazar con la referencia posteriorO con awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Tenga en cuenta que en los shells modernos también puede usar una matriz en lugar de una variable normal. En bash
puedes 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 utilizas la variable.
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
Y el de grep oneliner con --perl-regexp
opción,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Explicación:
(?<=^\")[^"]*
-> Aquí se usa un lookbehind. Coincide con cualquier carácter pero no "
cero o más veces (una vez que encuentra comillas dobles, deja de coincidir) que están justo después de las comillas dobles (solo la línea que comienza con comillas dobles).
Otro truco feo sed
,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
Dado que regex tiene modos codiciosos y no codiciosos, si tiene múltiples objetivos en la misma línea, no se extraerá como desee. Línea:
"tom" is a cat, and "jerry" is a mouse.
Objetivo:
tom
jerry
Comando (modo codicioso):
grep -oP '".*"' name
Comando (modo no codicioso):
grep -oP '".*?"' name
tr -d \"
Es otra forma de eliminar las comillas. (tr
normalmente traduce un conjunto de caracteres en otro;-d
le dice que simplemente los elimine en su lugar).