J'ai un certain nombre de lignes récupérées à partir 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 se composent de xyz en conséquence.
Maintenant, je dois traiter chaque ligne obtenue à la suite de la commande grep. Comment procéder pour cela?
grep -o
ce genre de chose. Le-o
drapeau ne rendra que le texte qui correspond, avec une correspondance par ligne de sortie. (Ce n'est pas exhaustif, doncecho aaa |grep 'a*'
ne vous donne que "aaa" et omet les trois correspondances partielles "", "a" et "aa")Réponses:
L'un des moyens les plus simples est de ne pas stocker la sortie dans une variable, mais de la parcourir directement avec une boucle while / read.
Quelque chose comme:
Il existe des variantes de ce schéma en fonction exactement de ce que vous recherchez.
Si vous avez besoin de changer des variables à l'intérieur de la boucle (et que ce changement soit visible à l'extérieur de celle-ci), vous pouvez utiliser la substitution de processus comme indiqué dans la réponse de fedorqui :
la source
while read p || [[ -n $p ]]; do ...
(emprunté à stackoverflow.com/questions/1521462/… )Vous pouvez faire la
while read
boucle suivante , qui sera alimentée par le résultat de lagrep
commande en utilisant la soi-disant substitution de processus:De cette façon, vous n'avez pas à stocker le résultat dans une variable, mais à "injecter" directement sa sortie dans la boucle.
Notez l'utilisation
IFS=
etread -r
selon les recommandations de BashFAQ / 001: Comment puis-je lire un fichier (flux de données, variable) ligne par ligne (et / ou champ par champ)? :Concernant la substitution de processus, elle est expliquée dans la page bash hackers :
la source
for
version. J'ai essayé de faire une boucle"${$(grep xyz abc.txt)[@]}"
comme dans stackoverflow.com/a/14588210/1983854 mais n'a pas pu. Alors je laisse juste la première version.zsh
, où ce type d'imbrication fonctionne probablement).while IFS= read -r result <&3
etdone 3< <(grep ...
Je suggérerais d'utiliser awk au lieu de grep + autre chose ici.
awk '$0~/xyz/{ //your code goes here}' abc.txt
la source
//your code goes here
?Sans aucune itération avec l'option grep --line-buffered:
Exemple réel avec une sortie de commande de débogage de routeur Symfony PHP Framework, pour grep toutes les routes liées à "api":
la source
tail -f some.log
, dans mon cas) ...Souvent, l'ordre du traitement n'a pas d'importance. GNU Parallel est fait pour cette situation:
Si votre traitement ressemble plus à:
et
myprogram
est lent alors vous pouvez exécuter:la source
Répétez les résultats de grep avec une boucle while / read. Comme:
la source
Pour ceux qui recherchent un monoplace:
la source