Bonjour,
Je souhaite placer le résultat d'un "grep" vers une variable
Actuellement j'exporte le résultat dans une fichier.
------extrait du fichier bash--------
var1="abc"
var2="abcdef"
echo $var1 | grep $var2 >result.tmp
read var3 < result.tmp
# Il doit y avoir plus simple ;-)
-------------------------------------------
remarque :
J'espérais que cette ligne ci-dessous fonctionnerait :
"echo $var1 | grep $var2 | read var3"
Mais var3 reste vide. Pourquoi ?
Merci de votre aide
Phildes
# Solution
Posté par Twidi (site web personnel) . Évalué à 5.
var3=`echo "$var1" | grep $var2`
[^] # Re: Solution
Posté par liberforce (site web personnel) . Évalué à 4.
var3=$(ma_commande)
les backquote (`) sont les guillemets inverses, assez peu utilisés en dehors de ce seul cas spécifique, et les débutants les confondent souvent avec les simple quote ('). Autant leur simplifier le boulot...
# Solution n°2
Posté par Sisyphe Plâtrier . Évalué à 5.
[^] # Re: Solutions
Posté par phildes . Évalué à 1.
Ca fonctionne très bien.
Phildes
PS : et bravo pour la rapidité de réponse... voir les horaires :-) des posts
# Le pourquoi
Posté par tgl . Évalué à 7.
Parce que ce les différente commandes d'un pipe sont éxécutées dans autant de sous-shells (des nouveaux processus si tu veux). Ton "read var3" positionne bien une variable var3, mais dans un de ces sous-shell, qui meure juste après, et qui n'affecte en rien l'environnement de ton script.
T'a déjà été donné la solution qui consiste à remplacer le read par une affectation avec var3=$(...). Bon, ça ça marche bien parceque tu fais un read tout simple. Mais juste pour ta culture, en Bash, une solution plus générique pour récupérer la sortie de commandes de sous-shells par une commande du shell principal serait d'utiliser ce genre de redirection là :
read a b c d <<<$(echo 192.128.1.1 | sed 's:\.:\n:g')
(heu bon, ouais, y'a moins moche pour faire ça, m'enfin c'est un exemple)
Oh, et puis aussi, si jamais t'es en Bash-3.0, sache que les expressions régulières sont supportées en natif, sans passer par grep, avec l'operateur '=~' et le tableau BASH_REMATCH pour les résultats. Par exemple:
[[ "${var1}" =~ "${var2}" ]] && var3=${BASH_REMATCH[0]}
Ça peut paraitre plus compliqué comme ça, mais franchement nan pas vraiment, et surtout c'est infiniment plus rapide, et ça compte si jamais ton truc est dans une boucle : répetée 10000 fois, la soluce avec $(...grep...) prend ici ~20 secondes (le fork de processus est qqch de coûteux), alors que celle là en prend ~0,2.
Bon et puis même si tu n'es pas en bash-3.0 et que donc tu n'a pas les regexp, n'oublies pas de jetter un oeil au paragraphe "Parameter Expansion" dans ton $(man bash), parceque ça aussi ça permet souvent d'éviter des grep ou des sed dans les cas simples. Je parle des opération du style varB=${varA%pattern} et compagnie.
[^] # Re: Le pourquoi
Posté par phildes . Évalué à 1.
> sont éxécutées dans autant de sous-shells
Je comprends mieux. Ca me rassure. J'avais un doute, je ne comprenais plus la notion de pipe.
> read a b c d <<<$(echo 192.128.1.1 | sed 's:\.:\n:g')
Effectivement, c'est puissant..
Merci pour ces explications claires et précises.
Phildes
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.