Forum Programmation.shell rediriger le résultat d'une commande vers une variable

Posté par  .
Étiquettes : aucune
0
5
juin
2005
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  (site web personnel) . Évalué à 5.

    Pour ta première question il faut utiliser les ` `

    var3=`echo "$var1" | grep $var2`
    • [^] # Re: Solution

      Posté par  (site web personnel) . Évalué à 4.

      Ou mieux, la variante
      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  . Évalué à 5.

    mavar=$(ls) marche aussi
    • [^] # Re: Solutions

      Posté par  . Évalué à 1.

      Merci à vous.

      Ca fonctionne très bien.

      Phildes

      PS : et bravo pour la rapidité de réponse... voir les horaires :-) des posts
  • # Le pourquoi

    Posté par  . Évalué à 7.

    > Mais var3 reste vide. Pourquoi ?

    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  . Évalué à 1.

      > Parce que ce les différente commandes d'un pipe
      > 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.