How can I exclude one word with grep?

955,975

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 greps:

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
Share:
955,975
john
Author by

john

Updated on July 25, 2022

Comments

  • john
    john almost 2 years

    I need something like:

    grep ^"unwanted_word"XXXXXXXX
    
    • Kanagavelu Sugumar
      Kanagavelu Sugumar almost 6 years
      grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"
  • DocWiki
    DocWiki almost 13 years
    Thanks for this, very useful! I would like to mention that The grep command is case sensitive by default
  • Andrey Regentov
    Andrey Regentov over 9 years
    what 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
    Matthew Read almost 9 years
    You should reverse the order to get highlighting on word1.
  • cybersoft
    cybersoft over 8 years
    Note that grep -v -P also works without negation in regular expression.
  • MBR
    MBR almost 8 years
    It appears to be much faster than the grep -P solution on big files.
  • fedorqui
    fedorqui almost 8 years
    @MBR grep -P means using Perl regexp, so loading that package is going to be way more expensive than a normal grep.
  • xuiqzy
    xuiqzy almost 8 years
    From 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
    adamski.pro over 7 years
    -v or --invert-match select non-matching lines. In your case grep -v 'unwanted_word' file or grep --invert-match 'unwanted_word' file.
  • Kanji Viroja
    Kanji Viroja over 7 years
    I want to ignore one line above and one line below with matching pattern then How can i achieve it?
  • benjaminz
    benjaminz over 7 years
    Awesome, 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
    greene about 6 years
    Weird, it's the top answer, but in some cases it's wrong! If I want to find sun, except when it is sunrise, grep sun|grep -v sunrise skips line that contain both sun and sunrise at once, that is not what I want. grep -P 'sun(?!rise)' is much better.
  • dwanderson
    dwanderson almost 6 years
    @greene provided the key - excluding the term in the same query. I'm using ag, not grep per se, and I can't pipe one ag to another. What I needed was (?!foo) - thanks!
  • patrick
    patrick over 5 years
    I guess it would clarify to add a placeholder for the file name to that example
  • allenyllee
    allenyllee over 5 years
    If 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
    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
    FantomX1 over 3 years
    However, 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
    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
    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
    Maëlan over 2 years
    The proposed pattern (?!.*unwanted_word)keyword only excludes lines where the unwanted_word starts after the keyword (possibly overlapped). To exclude any line that contains the unwanted_word, regardless of its position relative to the keyword, use ^(?!.*unwanted_word).*\Kkeyword .