J'ai une sortie VBoxManage list vms
qui ressemble à ceci:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Je dois saisir les noms arch
et arch2
et les enregistrer dans une variable.
J'ai une sortie VBoxManage list vms
qui ressemble à ceci:
"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}
Je dois saisir les noms arch
et arch2
et les enregistrer dans une variable.
Réponses:
Cela analysera le contenu de ces 2 chaînes:
$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2
Ce qui précède recherche une chaîne correspondant au modèle ".*"
. Cela correspondra à tout ce qui se produit entre guillemets doubles. Ainsi grep
, ces types de valeurs seront renvoyés:
"arch"
"arch2"
Le tuyau à sed
supprimer toutes les guillemets doubles de ces chaînes en vous donnant les chaînes que vous recherchez. La notation sed 's/"//g'
est instruisait sed
de faire une recherche et remplacer sur toutes les occurrences de guillemets doubles, les remplacer par rien, s/"//g
. La commande s/find/replace/g
est ce qui se passe là-bas, et la fin g
de la recherche lui dit de le faire globalement sur toute la chaîne qui lui est donnée.
Vous pouvez également utiliser sed
pour couper le guillemet double de début, conserver ce qui se trouve entre les deux et couper le devis restant + tout ce qu'il y a après:
$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2
$ grep -o '".*"' somefile | tr -d '"'
arch
arch2
La commande tr
peut être utilisée pour supprimer des caractères. Dans ce cas, il supprime les guillemets doubles.
$ grep -oP '(?<=").*(?=")' somefile
arch
arch2
En utilisant grep
la fonction PCRE de, vous pouvez rechercher toutes les sous-chaînes commençant par un guillemet double ou se terminant par un guillemet double et signaler uniquement la sous-chaîne.
/address/
to sed
like, sed '/^"\(arch[^"]*\)/s//\1/
vous n'opérerez que sur les lignes contenant cette chaîne.
sed
devriez vraiment faire s/^"\([^"]*\)".*/\1/
au cas où il n'y aurait que deux guillemets sur la ligne.
C'est un autre travail pour cut
:
VBoxManage list vms | cut -d \" -f2
cut
divise chaque ligne en champs en utilisant le guillemet comme délimiteur, puis affiche le champ 2: le champ 1 est la chaîne vide avant le premier devis, le champ 2 est la chaîne souhaitée entre les guillemets et le champ 3 est le reste de la ligne.
Avec sed
vous pouvez faire:
var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')
Explication:
s/.../.../
- correspondre et remplacer^
- match en début de ligne\(...\)
- ceci est une référence arrière, nous pouvons nous référer à ce qui est apparié ici plus tard avec \1
[^"]*
- correspondre à toute séquence qui ne contient pas de "
(c'est-à-dire jusqu'à la suivante "
).*
- correspondre au reste de la ligne\1
- remplacer par la référence arrièreOu avec awk
:
var=$(VBoxManage list vms | awk -F\" '{ print $2 }')
Notez que dans les shells modernes, vous pouvez également utiliser un tableau au lieu d'une variable normale. En bash
vous pouvez faire:
IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"
Cela pourrait être plus facile lorsque vous utilisez la variable.
En utilisant bash, j'écrirais:
while read vm value; do
case $vm in
'"arch"') arch=$value ;;
'"arch2"') arch2=$value ;;
esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2
Et celui via grep oneliner avec --perl-regexp
option,
VBoxManage list vms | grep -oP '(?<=^\")[^"]*'
Explication:
(?<=^\")[^"]*
-> Un lookbehind est utilisé ici. Il correspond à n'importe quel caractère mais pas à "
zéro ou plusieurs fois (une fois qu'il trouve des guillemets doubles, il cesse de correspondre) qui se trouvent juste après les guillemets doubles (uniquement la ligne qui commence par des guillemets doubles).
Un autre hack laid à travers sed
,
$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2
puisque regex a des modes gourmands et non gourmands, si vous avez plusieurs cibles sur la même ligne, il ne sera pas extrait comme vous le souhaitez. Ligne:
"tom" is a cat, and "jerry" is a mouse.
Cible:
tom
jerry
Commande (mode gourmand):
grep -oP '".*"' name
Commande (mode non gourmand):
grep -oP '".*?"' name
tr -d \"
est une autre façon de supprimer les guillemets. (tr
traduit normalement un jeu de caractères en un autre; lui-d
dit de simplement les supprimer à la place.)