web-dev-qa-db-fra.com

Comment traiter chaque ligne reçue à la suite de la commande grep

J'ai un certain nombre de lignes extraites d'un fichier après avoir exécuté la commande grep comme suit:

var=`grep xyz abc.txt`

Disons que j’ai 10 lignes, qui consistent en xyz.

Maintenant, je dois traiter chaque ligne obtenue à la suite de la commande grep. Comment puis-je procéder pour cela?

119
P_Jain

L'un des moyens les plus simples consiste à ne pas stocker la sortie dans une variable, mais à la parcourir directement avec une boucle while/read.

Quelque chose comme:

grep xyz abc.txt | while read -r line ; do
    echo "Processing $line"
    # your code goes here
done

Ce schéma varie en fonction de ce que vous recherchez.

Si vous devez modifier des variables dans la boucle (et que cette modification soit visible en dehors de celle-ci), vous pouvez utiliser la substitution de processus comme indiqué dans fedorqui answer :

while read -r line ; do
    echo "Processing $line"
    # your code goes here
done < <(grep xyz abc.txt)
218
Mat

Vous pouvez effectuer la boucle while read suivante, qui sera alimentée par le résultat de la commande grep en utilisant le processus de substitution de processus:

while IFS= read -r result
do
    #whatever with value $result
done < <(grep "xyz" abc.txt)

De cette façon, vous ne devez pas stocker le résultat dans une variable, mais directement "injecter" sa sortie dans la boucle.


Notez l'utilisation de IFS= et read -r conformément aux recommandations de BashFAQ/001: Comment lire un fichier (flux de données, variable) ligne par ligne (et/ou champ par champ)? :

L’option -r à lire empêche l’interprétation de la barre oblique inversée (généralement utilisée En tant que paire de nouvelle ligne oblique inversée, pour continuer sur plusieurs lignes ou pour échapper aux délimiteurs). Sans cette option, les barres obliques inverses non échappées dans l'entrée sera ignoré. Vous devriez presque toujours utiliser le -r option à lire.

Dans le scénario ci-dessus, IFS = empêche le rognage du début et de la fin les espaces blancs. Supprimez-le si vous voulez cet effet.

En ce qui concerne la substitution de processus, il est expliqué dans la page bash hackers :

La substitution de processus est une forme de redirection où l'entrée ou la sortie d'un processus (une séquence de commandes) apparaît comme un temporaire fichier.

17
fedorqui

Je suggérerais d'utiliser awk au lieu de grep + quelque chose d'autre ici.

awk '$0~/xyz/{ //your code goes here}' abc.txt

8
Julien Grenier

Souvent, l'ordre du traitement n'a pas d'importance. GNU Parallel est créé pour cette situation:

grep xyz abc.txt | parallel echo do stuff to {}

Si votre traitement ressemble plus à:

grep xyz abc.txt | myprogram_reading_from_stdin

et myprogram est lent, alors vous pouvez exécuter:

grep xyz abc.txt | parallel --pipe myprogram_reading_from_stdin
0
Ole Tange