How can I exclude one word with grep?
Solution 1
You can do it using -v
(for --invert-match
) option of grep as:
grep -v "unwanted_word" file | grep XXXXXXXX
grep -v "unwanted_word" file
will filter the lines that have the unwanted_word
and grep XXXXXXXX
will list only lines with pattern XXXXXXXX
.
EDIT:
From your comment it looks like you want to list all lines without the unwanted_word
. In that case all you need is:
grep -v 'unwanted_word' file
Solution 2
I understood the question as "How do I match a word but exclude another", for which one solution is two greps in series: First grep finding the wanted "word1", second grep excluding "word2":
grep "word1" | grep -v "word2"
In my case: I need to differentiate between "plot" and "#plot" which grep's "word" option won't do ("#" not being a alphanumerical).
Hope this helps.
Solution 3
If your grep
supports Perl regular expression with -P
option you can do (if bash; if tcsh you'll need to escape the !
):
grep -P '(?!.*unwanted_word)keyword' file
Demo:
$ cat file
foo1
foo2
foo3
foo4
bar
baz
Let us now list all foo
except foo3
$ grep -P '(?!.*foo3)foo' file
foo1
foo2
foo4
$
Solution 4
The right solution is to use grep -v "word" file
, with its awk
equivalent:
awk '!/word/' file
However, if you happen to have a more complex situation in which you want, say, XXX
to appear and YYY
not to appear, then awk
comes handy instead of piping several grep
s:
awk '/XXX/ && !/YYY/' file
# ^^^^^ ^^^^^^
# I want it |
# I don't want it
You can even say something more complex. For example: I want those lines containing either XXX
or YYY
, but not ZZZ
:
awk '(/XXX/ || /YYY/) && !/ZZZ/' file
etc.
Solution 5
Invert match using grep -v:
grep -v "unwanted word" file pattern
john
Updated on July 25, 2022Comments
-
john almost 2 years
I need something like:
grep ^"unwanted_word"XXXXXXXX
-
Kanagavelu Sugumar almost 6 years
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"
-
-
DocWiki almost 13 yearsThanks for this, very useful! I would like to mention that The grep command is case sensitive by default
-
Andrey Regentov over 9 yearswhat if I want to exclude N lines after the line with "unwanted word" as well?
-v 'unwanted_word' --after N
doesn't help because it INCLUDES the line and N lines after. -
Matthew Read almost 9 yearsYou should reverse the order to get highlighting on
word1
. -
cybersoft over 8 yearsNote that
grep -v -P
also works without negation in regular expression. -
MBR almost 8 yearsIt appears to be much faster than the
grep -P
solution on big files. -
fedorqui almost 8 years@MBR
grep -P
means using Perl regexp, so loading that package is going to be way more expensive than a normalgrep
. -
xuiqzy almost 8 yearsFrom the man page: "-L, --files-without-match Suppress normal output; instead print the name of each input file from which no output would normally have been printed. The scanning will stop on the first match." (Emphasis by me) So beware of this!
-
adamski.pro over 7 years
-v
or--invert-match
select non-matching lines. In your casegrep -v 'unwanted_word' file
orgrep --invert-match 'unwanted_word' file
. -
Kanji Viroja over 7 yearsI want to ignore one line above and one line below with matching pattern then How can i achieve it?
-
benjaminz over 7 yearsAwesome, I use this in git to quickly peruse the status of my repo, works like a charm:
git status -s |grep -v "folder_I_dont_care"
-
greene about 6 yearsWeird, it's the top answer, but in some cases it's wrong! If I want to find
sun
, except when it issunrise
,grep sun|grep -v sunrise
skips line that contain bothsun
andsunrise
at once, that is not what I want.grep -P 'sun(?!rise)'
is much better. -
dwanderson almost 6 years@greene provided the key - excluding the term in the same query. I'm using
ag
, notgrep
per se, and I can't pipe oneag
to another. What I needed was(?!foo)
- thanks! -
patrick over 5 yearsI guess it would clarify to add a placeholder for the file name to that example
-
allenyllee over 5 yearsIf you want to bring the regex power into the exclude pattern, just add
-E
. e.g.grep -v -E "unwanted_pattern_in_regex" file
-
Gabriel Staples about 4 years"if bash...you'll need to escape the
!
". Thank you thank you thank you! That's what I wanted! -
FantomX1 over 3 yearsHowever, this doesn't work in a way of `grep -P '(?!.*foo3)[a-zA-Z0-9]*' pattern, it won't find what you want to omit, but will find only the exact thing, so regexp is little useless for an exact phrases
-
Nico about 3 years@MatthewRead I find it really more logic like this. First you're looking for occurences of "word1" then remove occurences found where there is also "word2" The opposite is strange : first removing "word2" and then looking the word you want. Maybe it's just a point of view
-
Matthew Read about 3 years@Nico There's no reason to continue sticking to you initial impulse after finding something more useful, though. If you use this a lot, I would recommend creating a shell function that you can call (like
xnoty() { grep -v "$2" | grep "$1" }
) so you don't have to remember the construction. -
Maëlan over 2 yearsThe proposed pattern
(?!.*unwanted_word)keyword
only excludes lines where theunwanted_word
starts after thekeyword
(possibly overlapped). To exclude any line that contains theunwanted_word
, regardless of its position relative to thekeyword
, use^(?!.*unwanted_word).*\Kkeyword
.