web-dev-qa-db-fra.com

Répétez les correspondances de ligne entière avec grep pour plusieurs instances sur la même ligne

Une ramification de this question:

Lors de la recherche de la chaîne "banana" dans le fichier suivant, nous aimerions respectivement 1,2,3 et 7 instances des lignes 1,2,3 et 4. Le nombre de sorties grep doit être égal au nombre d'instances de correspondance tout en renvoyant la ligne entière.

There is one banana here
There are two banana banana here
There are three banana banana banana here
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
In fact we need not have any too!

Remarque: Si nous supprimons la restriction des lignes entières dans la sortie, nous avons:

grep -no "banana" tempfile 

qui revient

1:banana
2:banana
2:banana
3:banana
3:banana
3:banana
4:banana
4:banana
4:banana
4:banana
4:banana
4:banana
4:banana

Des idées?

EDIT: Ceci est la sortie prévue

1 There is one banana here
2 There are two banana banana here
2 There are two banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
1
Manoj Kumar

grep n'a pas de compteur pour les correspondances, seulement -c compteur pour les lignes qui correspondent, mais nous pouvons utiliser awk pour le faire. Si je comprends bien, vous souhaitez imprimer la ligne qui correspond à x nombre de fois en fonction du nombre de correspondances. Eh bien, le voici:

$ awk '{for(i=1;i<=NF;i++) if($i=="banana") counter++;for(j=1;j<=counter;j++) print NR,$0;counter=0 }' input.txt         
1 There is one banana here
2 There are two banana banana here
2 There are two banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have

L'idée de base ici est que nous bouclons sur chaque mot d'une ligne et que nous comptions les correspondances. S'il y a une correspondance, nous incrémentons le compteur puis utilisons ce compteur pour imprimer la même ligne en boucle. Enfin, le compteur est réinitialisé et le processus se répète

2
Sergiy Kolodyazhnyy

En utilisant l'opérateur de répétition de chaîne Perl, obtenir le nombre de répétitions en évaluant le résultat de la correspondance dans un contexte scalaire:

$ Perl -pe '$_ x= (() = /banana/g)' file
There is one banana here
There are two banana banana here
There are two banana banana here
There are three banana banana banana here
There are three banana banana banana here
There are three banana banana banana here
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
3
steeldriver

Ce n'est pas très joli, mais vous pouvez utiliser quelque chose comme

awk '{print NR, gsub(/banana/, "")' <tempfile

Il fonctionne en utilisant la commande awkgsub pour remplacer le modèle de correspondance (ici, banane) et il renvoie le nombre de fois qu'il effectue la substitution. Si sort ensuite le numéro de ligne d'entrée et le nombre de correspondances

Ou pour répéter la ligne d'entrée plusieurs fois

awk '{A=$0
b=gsub(/banana/, "")
for (i=1; i<=b; i++) print A
}' <tempfile
0
Nick Sillito