Grep recherche des chaînes avec des sauts de ligne
Comment utiliser grep pour la sortie des occurrences de la chaîne "exporter vers excel" dans les fichiers d'entrée donnée ci-dessous? Plus précisément, comment gérer les sauts de ligne qui se produisent entre les chaînes de recherche? Est-il un interrupteur dans le grep qui peuvent le faire ou d'une autre commande sans doute?
Fichiers d'entrée:
Fichier a.txt:
bla bla ... l'exportation vers
excel ...
bla bla..
Fichier b.txt:
bla bla ... exporter vers excel ...
bla bla..
Ce que je comprends (référence: Unix, les Outils électriques) grep famille de programmes sont en ligne orientée, lire une ligne à la fois et ne peut donc pas trouver des modèles à travers la ligne. Ainsi, vous pouvez penser d'un script perl ou utiliser sed ici. HTH.
comment utiliser sed dans ce contexte?
echo-e "foo\nbar" | sed -n 'N;/foo\nbar/p'
Qui ne trouve pas de "foo bar". Voir ma réponse ci-dessous.
Oui, je sais; il trouve "foo\nbar" qui a été une démonstration de Vijay sur la façon sed peuvent être utilisés pour attraper les cordes avec des sauts de ligne entre eux.
comment utiliser sed dans ce contexte?
echo-e "foo\nbar" | sed -n 'N;/foo\nbar/p'
Qui ne trouve pas de "foo bar". Voir ma réponse ci-dessous.
Oui, je sais; il trouve "foo\nbar" qui a été une démonstration de Vijay sur la façon sed peuvent être utilisés pour attraper les cordes avec des sauts de ligne entre eux.
OriginalL'auteur Vijay Dev | 2009-12-07
Vous devez vous connecter pour publier un commentaire.
Ne vous voulez juste de trouver les fichiers qui contiennent le motif, en ignorant mais les sauts de ligne, ou voulez-vous pour voir la correspondance des lignes?
Si l'ancien, vous pouvez utiliser
tr
pour convertir les sauts de ligne pour les espaces:Si cette dernière option, vous pouvez faire la même chose, mais vous pouvez utiliser l'option-o indicateur pour imprimer seulement la concordance réelle. Vous aurez alors voulez ajuster votre regex pour inclure tout autre contexte que vous souhaitez.
OriginalL'auteur Laurence Gonsalves
Je ne sais pas comment faire cela dans le grep. J'ai vérifié la page de man pour
egrep(1)
et il peut ne pas correspondre avec un saut de ligne dans le milieu.J'aime la solution @Laurence Gonsalves suggérées, à l'aide de
tr(1)
pour anéantir les retours à la ligne. Mais comme il a dit, il va être une douleur pour imprimer la correspondance des lignes si vous le faites de cette façon.Si vous voulez match malgré un retour à la ligne et ensuite imprimer le correspondant de ligne(s), je ne peux pas penser à une façon de le faire avec grep, mais il serait pas trop dur dans l'un de Python, AWK, Perl ou Ruby.
Voici un script Python qui permet de résoudre le problème. J'ai décidé que, pour les lignes que seul match quand il s'est joint à la ligne précédente, je voudrais imprimer un
-->
flèche avant de la deuxième ligne de la correspondance. Les lignes qui correspondent à carrément sont toujours imprimés sans la flèche.C'est écrit en supposant que /usr/bin/python Python 2.x. Vous pouvez trivialement modifier le script sous Python 3.x si vous le souhaitez.
EDIT: ajout des commentaires.
J'ai rencontré des problèmes pour le faire imprimer le bon nombre de ligne sur chaque ligne en utilisant un format similaire à ce que vous obtiendriez avec
grep -Hn
.Il peut être beaucoup plus courte et la plus simple si vous n'avez pas besoin des numéros de ligne, et vous n'avez pas l'esprit la lecture de l'ensemble du dossier à la fois dans la mémoire:
re.MULTILINE était pas ce que je voulais, donc je n'ai pas le spécifier. Avec re.MULTILIGNE, la
re
code traite d'un retour à la ligne comme à la fin d'une chaîne, et ne correspond pas à la suite. Je voulais un retour à la ligne traitée comme n'importe quel autre espace blanc dans la correspondance. Je vais ajouter quelques commentaires sur le code.En fait, ma première version serait la même avec ou sans le re.MULTILINE. La deuxième, buvez-en-entier-version du fichier ne doit pas avoir ce drapeau car il dépend de la correspondance autour d'un retour à la ligne. La première version s'appuie une spéciale unique de la ligne et de bandes un caractère de nouvelle ligne dans le processus.
OriginalL'auteur steveha
grep -A1 "exporter vers" nom de fichier | grep -B1 "excel"
Il également ne pas correspondre à l'exportation "\npour excel" et n'évoluent pas à la recherche d'une chaîne de caractères qui contient de nombreux espaces.
OriginalL'auteur christian.buggle
J'ai testé un peu et il semble fonctionner:
Vous pouvez vous permettre un certain espace blanc supplémentaire à la fin et au début de l'lignes comme ceci:
OriginalL'auteur Dennis Williamson
utilisation gawk. définissez le séparateur d'enregistrement, au format excel, puis vérifiez pour "exporter vers".
ou
grep
(pour les matchs à l'intérieur de sa capacité)?imprimer le dossier, $0. Sinon, je ne comprends pas ce que tu veux dire.
Je pense que votre travail d'édition qui s'en occupe. Cependant, il échoue pour certains cas limites. Si l'entrée était quelque chose comme "export excel\nexcel" ou "exporter vers\nsomething autres que excel", par exemple. Pour répondre à votre question dans votre commentaire: original de one-liner, si 0 $ont été ajoutés à la sortie, ne serait pas montrer la "excel" et surtout les "..." après ce qui est indiqué dans le cas des OP question.
OriginalL'auteur ghostdog74