For grepping line-by-line in a file filename, I often find these very useful
Match pattern1
OR pattern2 in the same line
:
$ grep -E 'pattern1|pattern2'
filename
Match pattern1
AND pattern2 in the same line
:
$ grep -E 'pattern1.*pattern2'
filename
The above command searches for pattern1
followed by pattern2
. If the order does not matter or you want to search them in either order, then use the follwoing
$ grep -E 'pattern1.*pattern2|pattern2.*pattern1'
filename
The pipe enables the OR search which we saw earlier. Another option for this situation (i.e., AND search when the order is not important):
$ grep -E 'pattern1' filename | grep -E 'pattern2'
which basically greps the STDOUT of the first grep.
Match pattern1
AND pattern2
, but NOT pattern3
in the same line:
$ grep -E 'pattern1.*pattern2'
filename | grep -Ev 'pattern3'
when the order of the first two patterns is important. When that order is NOT important:
$ grep -E 'pattern1' filename | grep -E 'pattern2' | grep -Ev 'pattern3'
Match pattern1
OR pattern2
, but NOT pattern3
in the same line:
$ grep -E 'pattern1|pattern2'
filename | grep -Ev 'pattern3'
N.B. (1) grep -E
may be replaced by egrep
.ย I used grep -E
everywhere in this post assuming a general case of regular expressions as patterns. Lowercase -e
is also used for regex, but this is more “basic” than -E
which supports “extended” regex, e.g. regular expression metacharacters like +, ?, | and (). (2) The -v
flag is for non-matching grep.
avinc said:
very useful, Thank for sharing
svet said:
thank you!!! very useful for newbie like me!!!
kousik said:
You are welcome ๐
yokmp said:
Match pattern1 but not 2:
grep -o “pattern1[^NOT]”
An ls -RA| grep -o “\./.*[^:]” will output all folders but not the files in them.
And ls -RA| grep -o “\./.*[^:]”|sed s#’./’#$PWD/# will do the same but extends the path …
kousik said:
Very nice! Thanks!
Pingback: (20120306) ์คํฌ๋ฉ – grep ์ฌ์ฉ์ and, or, not ์ ์ฉํ์ฌ ํํฐ๋งํ๊ธฐ » Think Like Feynman
black water said:
My brother recommended I might like this web site.
He was entirely right. This post actually made my day.
You can not imagine simply how much time I had spent for this information!
Thanks!
ad84 said:
> grep -E ‘pattern1.*pattern2|pattern2.*pattern1’ filename
I just wasted a solid hour before I realized that the dot in grep doesn’t normally match newlines.
Something like grep pat2 $(grep -rlE pat1 .) will match pat1 AND pat2 even if they are on different lines.
ad84 said:
I learned something today: matching lines (what the article is about) !=looking for text in files (what I was doing.)
ad84 said:
s/before/until/
hindsights2030 said:
Reblogged this on Hindsight's 20/30 and commented:
My audible work-place utterance on finding a solution to my grep problem on this blog post: “Goddamnit, I love Linux so much!”