grep entourant les personnages d'un match

8

Je cherche à faire une recherche et un remplacement dans un vidage de base de données géant, et il ne fait pas ce que je pense devrait se produire. Je voudrais grep pour ma chaîne cible dans le fichier, puis voir les 8 caractères environnants environ (je pourrais avoir besoin d'ajuster ce nombre, selon). Comment puis je faire ça?

La raison pour laquelle je ne peux pas regarder cela est parce qu'il y a plusieurs centaines, voire des milliers de matchs. Je veux obtenir un certain nombre de caractères entourant la chaîne, puis la canaliser uniqou quelque chose pour voir pourquoi ma recherche et remplacement a des comportements inattendus.

De plus, il peut y avoir plusieurs correspondances sur la même ligne!

user394
la source
Ce n'est pas un fichier texte?
enzotib
C'est vrai, mais même les correspondances sont trop volumineuses pour le globe oculaire.
user394

Réponses:

12

La manière grossière d'utiliser grepserait quelque chose comme

grep -o "....yourtext...." /path/to/the/dump.sql

Le nombre de points correspond au nombre de caractères avant / après le texte saisi. L' -ooption rend la grepsortie uniquement les correspondances, pas les lignes entières.

Pour l'utiliser uniqsur la sortie, n'oubliez pas que vous devez d'abord trier la sortie. Donc, généralement, vous feriez

grep . . . | sort | uniq

Si vous êtes intéressé par le nombre de résultats pour chaque correspondance, vous pouvez obtenir une sortie agréable en utilisant

grep . . . | sort | uniq -c | sort -n
rozcietrzewiacz
la source
Brut? Complètement sophistiqué!
user394
1
Vous pouvez développer cela un peu en utilisant l'opérateur de répétition: grep -o '.\{8\}yourtext.\{8\}'. C'est un peu moins étourdissant que de compter 8 points.
Caleb
:) Par grossier, je veux dire que vous ne jouez pas avec des choses comme le comptage des caractères correspondants (en utilisant des plages) ou le rétrécissement des jeux de caractères.
rozcietrzewiacz
@Caleb et user394: C'est exactement ce que j'avais l'intention de ne pas suggérer (et j'ai donc appelé ma méthode "brute"). De plus, il n'est pas nécessaire de se souvenir de la construction de l'opérateur de répétition - il est encore plus rapide de taper "....." que ". \ {6 \}".
rozcietrzewiacz
7

À partir de la réponse de @rozcietrzewiacz, je peux développer

pattern="string"
num=8
grep -on ".\{0,$num\}$pattern.\{0,$num\}" input-file
enzotib
la source
1
La séquence de points "brute" est de mieux en mieux tout le temps :)
Caleb
1
@Caleb: en général, la réponse "grossière" est un bon début, mais parfois on veut en dire un peu plus.
enzotib
1
La méthode de séquence de points ne trouvera pas de motifs cibles justifiés à gauche ou à droite; cette méthode sera. (+1)
Peter.O
2
PS .. Je viens de remarquer qu'il n'attrapera pas plusieurs instances de motif sur la même ligne (comme l'OP mentionné) lorsque la portée du texte `` exta '' de fin du premier motif chevauche la portée du texte `` extra '' principal du motif suivant
Peter.O
@fred: oui, -one donne que le premier match lorsque deux matchs se chevauchent:echo 'aaabbbccc' | grep -o 'bb
enzotib