简体   繁体   中英

Matching keywords across multiple lines

The utility grep could search a patter or multiple patterns in one line, but some times these multiple pattern could be split into multiple lines (for example, to keep the previous line not exceed 80 characters in a line). Is there a easy to make such search? A line range parameter is better to be specified which means only output the range if given patterns appear in given number of lines range.

EDIT: adding the expected usage could be like below:

grep -l2 'abc.*def' file.txt

--- below pattern will be selected out

abc
def

--- but below pattern will not be selected.

abc
xxx
def

Seems like you're trying to print the lines which are in a range ie, from abc to def . If yes, then you could use the below regex.

grep -oPz '(?s)abc.*?def' file

(?s) DOTALL mode, which turns dot in our regex to match even line breaks.

From grep --help

 -z, --null-data           a data line ends in 0 byte, not newline
 -P, --perl-regexp         PATTERN is a Perl regular expression
 -o, --only-matching       show only the part of a line matching PATTERN

Example:

$ cat file
foo
abc
xxx
def
bar
$ grep -oPz '(?s)abc.*?def' file
abc
xxx
def
$ grep -oPz 'abc(.*\n){1}.*' file
abc
xxx
$ grep -oPz 'abc(.*\n){2}.*' file
abc
xxx
def

Assuming this is input:

cat file    
foo
abc
xxx
def
bar
abc
def
baz
abc foo bar def
yyy

You can use this awk:

awk '/abc/{p=NR;s=$0} /def/&&NR<=p+1{if (NR>p) print s; print $0}' file
abc
def
abc foo bar def

Or this grep:

grep -ozP 'abc([^\n]*\n)?[^\n]*def' file
abc
def
abc foo bar def

Both these commands will find text between abc and def with not more than one optional new line between them,.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM