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.

Tuxnani
la source
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 
arash kordi
la source
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.

null révolution
la source
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.
Manikandan Rajendran
la source
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

rubystallion
la source
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 .

Kenorb
la source
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
2

Viens juste de trouver

grep $'\r'

Il est utilisé $'\r'pour l'évasion de style C dans Bash.

dans cet article

HHHartmann
la source