Comment donner un motif pour une nouvelle ligne dans grep?


95

Comment donner un motif pour une nouvelle ligne dans grep? Nouvelle ligne au début, nouvelle ligne à la fin. Pas la manière d'expression régulière. Quelque chose comme \ n.


6
Ce que vous voulez n'est pas clair. new line at the beginningest une ligne vide et new line at ends'applique à chaque ligne du fichier. Pouvez-vous poster un exemple?
PP

2
En fait, vous pouvez simplement utiliser $. C'est un peu limité, mais utilisable dans des cas simples.
Krzysztof Jabłoński

Réponses:


84

grep les motifs sont comparés à des lignes individuelles, il n'y a donc aucun moyen pour un motif de correspondre à une nouvelle ligne trouvée dans l'entrée.

Cependant, vous pouvez trouver des lignes vides comme ceci:

grep '^$' file
grep '^[[:space:]]*$' file # include white spaces 

Au moins GNU grep a l'option -z qui fait que grep coupe les lignes par un caractère nul. Cependant, il ne semble pas prendre en charge la nouvelle ligne ou \ n dans le modèle pour correspondre à la nouvelle ligne, voir rapport de bogue .
jarno

1
@jarno Il prend en charge \ n dans les modèles avec le drapeau -P
rubystallion

92

essayez pcregrepau lieu de régulier grep:

pcregrep -M "pattern1.*\n.*pattern2" filename

L' -Moption lui permet de correspondre sur plusieurs lignes, vous pouvez donc rechercher des nouvelles lignes en tant que \n.


22

Vous pouvez utiliser cette façon ...

grep -P '^\s$' file
  • -Pest utilisé pour les expressions régulières Perl (une extension de POSIX grep).
  • \scorrespond aux caractères d'espacement; s'il est suivi de *, il correspond également à une ligne vide.
  • ^correspond au début de la ligne. $correspond à la fin de la ligne.

2
-Pest une extension GNU. Je suis très bien pour l'utiliser lorsque la situation l'exige (généralement lookahead / lookbehind), mais POSIX grep peut le faire simplement avec [[:space:]].
jordanm

1
Les pages de manuel grep de FWIW, Solaris et BSD (sans vérifier les autres) ont toutes deux un paragraphe pour -P. GNU est de toute façon assez standard. :)
K3 --- rnc

1
Depuis la page de manuel: [-P] Cette option n'est pas prise en charge dans FreeBSD.
Marián Černý

Non [-P] pour MacOsX non plus: grep [-abcdDEFGHhIiJLlmnOopqRSsUVvwxZ] [-A num] [-B num] [-C [num]] [-e modèle] [-f fichier] [--binary-files = valeur] [--color [= quand]] [--colour [= quand]] [--context [= num]] [--label] [--line-buffered] [--null] [pattern] [file. ..]
Niccolò

@ Niccolò Vous voudrez brew install grepobtenir GNU grep, qui est supérieur à plusieurs égards. apple.stackexchange.com/questions/193288/…
herdrick

19

Grâce à @jarno, je connais l'option -z et j'ai découvert que lors de l'utilisation de GNU grep avec l'option -P, la correspondance avec \nest possible . :)

Exemple:

grep -zoP 'foo\n\K.*'<<<$'foo\nbar'

Tirages bar


1
Super, notez que je ne reçois pas de notification concernant le "@jarno" dans la réponse.
jarno

3
C'est bien! Merci beaucoup d'avoir partagé!
Alicia Tang

6

En ce qui concerne la solution de contournement (sans utiliser de non portable -P), vous pouvez remplacer temporairement un caractère de nouvelle ligne par le différent et le modifier, par exemple:

grep -o "_foo_" <(paste -sd_ file) | tr -d '_'

Fondamentalement, il recherche une correspondance exacte _foo__signifie \n(so __= \n\n). Vous n'avez pas besoin de le traduire en arrière tr '_' '\n', car chaque motif serait imprimé dans la nouvelle ligne de toute façon, il _suffit donc de le supprimer .


pardonnez mon ignorance, mais l'utilisation de la substitution de processus n'est-elle pas encore une autre fonctionnalité compatible NON posix, donc non portable? dans le shell posix je ne pouvais pas faire <(p paste -sd_ file )?
humanityANDpeace

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.