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.