Passez la sortie de la command précédente à la suivante en tant qu'argument

J'ai une command qui command1 -p=aaa -v=bbb -i=4 données à stdout ( command1 -p=aaa -v=bbb -i=4 ). La ligne de sortie peut avoir la valeur suivante:

 rate (10%) - name: value - 10Kbps 

Je veux grep cette sortie afin de stocker ce «taux» (je suppose que le tuyau sera utile ici). Et enfin, je voudrais que ce taux soit la valeur d'un paramètre sur une deuxième command (disons command2 -t=${rate} )

Il semble être difficile de mon côté; Je voudrais savoir comment utiliser les pipes, grep, sed et ainsi de suite.

J'ai essayé beaucoup de combinaisons comme celle-là mais je suis confus de celles-ci:

 $ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate} 

    Vous confondez deux types d'inputs très différents.

    1. Entrée standard ( stdin )
    2. Arguments de command line

    Ceux-ci sont différents et sont utiles à des fins différentes. Certaines commands peuvent prendre des inputs dans les deux sens, mais elles les utilisent généralement différemment. Prenez par exemple la command wc :

    1. Passage de l'input par stdin :

       ls | wc -l 

      Cela countra les lignes dans la sortie de ls

    2. Transmettre l'input par des arguments de command line:

       wc -l $(ls) 

      Cela countra les lignes dans la list des files imprimés par ls

    Des choses complètement différentes.

    Pour répondre à votre question, il semble que vous voulez capturer le taux de la sortie de la première command, puis utiliser le taux comme argument de command line pour la deuxième command. Voici une façon de le faire:

     rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p') command2 -t "rate was $rate" 

    Explication du sed :

    • Le s/pattern/replacement/ command est de replace un model
    • Le motif signifie: la ligne doit commencer par "rate" ( ^rate ) suivi de deux caractères ( .. ), suivi de 0 ou de plus de numbers, suivi d'un % , suivi du rest du text ( .* )
    • \1 dans le rlocation signifie le contenu de la première expression capturée dans \(...\) , donc dans ce cas les numbers avant le signe %
    • Le drapeau -n de la command sed signifie qu'il ne faut pas imprimer les lignes par défaut. Le p à la fin de la command s/// signifie imprimer la ligne s'il y a un rlocation. En bref, la command n'imprimera quelque chose que s'il y a une correspondance.

    Pour simuler la sortie de command1 j'utilise cette instruction echo:

     $ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar" $ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"' 

    Un test rapide:

     $ command1 Blah rate (10%) - name: value - 10Kbps Blag 

    C'est tout bon, alors faisons-en l'parsing:

     $ command1 | grep 'rate' rate (10%) - name: value - 10Kbps 

    Donc, nous obtenons la ligne que nous voulons de command1 , laisse passer cela dans command2 :

     $ alias command2='echo' $ command2 -t="rate was "$(command1 | grep 'rate') -t=rate was rate (10%) - name: value - 10Kbps 

    Je m'attends à ce que "rate was "$(command1 | grep 'rate') pour concaténer automatiquement. Si cela ne fonctionne pas à cause des espaces, vous devriez pouvoir passer l'input comme ceci:

     $ alias command2='echo' $ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"') -t="rate was rate (10%) - name: value - 10Kbps " 

    Essayez ceci en utilisant grep & pcre :

     command | grep -oP '\$>\s+rate\s+\(\K[^\)]+' 

    La première tâche consiste à extraire le taux de cette ligne. Avec GNU grep (Linux non embedded ou Cygwin), vous pouvez utiliser l'option -o . La partie que vous voulez est celle qui ne contient que des numbers et suivie d'un signe % . Si vous ne souhaitez pas extraire le % lui-même, vous avez besoin d'une astuce supplémentaire: une assertion de lookahead de zéro largeur , qui ne correspond à rien mais uniquement si rien n'est suivi de % .

     command1 -p=aaa -v=bbb -i=4 | grep -o -P '[0-9]+(?=%)' 

    Une autre possibilité est d'utiliser sed. Pour extraire une partie d'une ligne dans sed, utilisez la command s , avec une regex qui correspond à la ligne entière (commençant par ^ et finissant par $ ), avec la partie à conserver dans un groupe ( \(…\) ). Remplacez toute la ligne par le contenu du groupe (s) à conserver. En général, passez l'option -n pour désactiver l'printing par défaut et mettez le modificateur p sur les lignes d'printing où il y a quelque chose à extraire (ici, il n'y a qu'une seule ligne, peu importe). Voir Renvoyer uniquement la partie d'une ligne après un motif correspondant et Extraction d'une expression régulière associée à «sed» sans imprimer les caractères environnants pour plus d'astuces.

     command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$/\1/' 

    Encore plus souple que sed, c'est awk. Awk exécute des instructions pour chaque ligne dans un petit langage impératif. Il y a plusieurs façons d'extraire le taux ici; Je sélectionne les deuxièmes champs (les champs sont délimités par des espaces par défaut), et supprime tous les caractères qui ne sont pas un chiffre.

     command1 -p=aaa -v=bbb -i=4 | awk '{gsub(/[^0-9]+/, "", $2); print $2}' 

    La prochaine étape, maintenant que vous avez extrait le taux, est de le passer en argument à command2 . L'outil pour cela est une command de sous-titrage . Si vous placez une command à l'intérieur de $(…) (parenthèses-dollar), sa sortie est remplacée par la command line. La sortie de la command est divisée en mots distincts à chaque bloc d'espace et chaque mot est traité comme un caractère générique; sauf si vous voulez que cela se produise, placez des guillemets autour de la substitution de command: "$(…)" . Avec les guillemets doubles, la sortie de la command est utilisée directement en tant que paramètre unique (la seule transformation est que les returns à la ligne à la fin de la sortie sont supprimés).

     command2 -t "$(command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$/\1/')" 

    Vous pouvez utiliser grep et c'est PCRE – Expressions régulières compatibles Perl. Cela vous permet d'utiliser un lookbehind pour correspondre à la valeur de taux, sans inclure la string "taux" dans vos résultats lorsque grepping pour cela.

    Exemple

     $ echo "rate (10%) - name: value - 10Kbps" | grep -oP '(?<=^rate \()\d+' 10 

    Détails

    Le grep ci-dessus fonctionne comme suit:

    • -o returnnera seulement ce que nous recherchons, \d+ , qui est les numbers dans les parens.
    • -P active la fonction PCRE de grep
    • (?<=^rate \() returnnera uniquement les strings commençant par "rate ("

    command2

    Pour attraper la valeur de "rate", vous pouvez exécuter command1 comme ceci:

     $ rate=$(command 1 | grep -oP '(?<=^rate \()\d+' 

    Ensuite, pour votre 2ème command, vous utiliserez simplement cette variable.

     $ command2 -t=${rate} 

    Vous pourriez get de la fantaisie et faire tout cela une ligne:

     $ command2 -t=$(command1 | grep -oP '(?<=^rate \()\d+') 

    Cela exécutera la command1 dans le bloc d'exécution $(..) , prendra ses résultats et les inclura dans le commutateur -t=.. command2.