ChatGPT解决这个技术问题 Extra ChatGPT

How can I exclude one word with grep?

I need something like:

grep ^"unwanted_word"XXXXXXXX
grep -Rv "word_to_be_ignored" . | grep "word_to_be_searched"

n
normanius

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

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.
-v or --invert-match select non-matching lines. In your case grep -v 'unwanted_word' file or grep --invert-match 'unwanted_word' file.
I want to ignore one line above and one line below with matching pattern then How can i achieve it?
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.
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
E
EdChum

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.


You should reverse the order to get highlighting on word1.
I guess it would clarify to add a placeholder for the file name to that example
@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
@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.
a
amos

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
$ 

Thanks for this, very useful! I would like to mention that The grep command is case sensitive by default
Note that grep -v -P also works without negation in regular expression.
"if bash...you'll need to escape the !". Thank you thank you thank you! That's what I wanted!
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
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 .
f
fedorqui

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.


It appears to be much faster than the grep -P solution on big files.
@MBR grep -P means using Perl regexp, so loading that package is going to be way more expensive than a normal grep.
g
garima

Invert match using grep -v:

grep -v "unwanted word" file pattern

S
Shriganesh Shintre

grep provides '-v' or '--invert-match' option to select non-matching lines.

e.g.

grep -v 'unwanted_pattern' file_name

This will output all the lines from file file_name, which does not have 'unwanted_pattern'.

If you are searching the pattern in multiple files inside a folder, you can use the recursive search option as follows

grep -r 'wanted_pattern' * | grep -v 'unwanted_pattern'

Here grep will try to list all the occurrences of 'wanted_pattern' in all the files from within currently directory and pass it to second grep to filter out the 'unwanted_pattern'. '|' - pipe will tell shell to connect the standard output of left program (grep -r 'wanted_pattern' *) to standard input of right program (grep -v 'unwanted_pattern').


s
st0le

The -v option will show you all the lines that don't match the pattern.

grep -v ^unwanted_word

W
Worthwelle

I excluded the root ("/") mount point by using grep -vw "^/".

# cat /tmp/topfsfind.txt| head -4 |awk '{print $NF}'
/
/root/.m2
/root
/var

# cat /tmp/topfsfind.txt| head -4 |awk '{print $NF}' | grep -vw "^/"
/root/.m2
/root
/var

b
bobble bubble

I've a directory with a bunch of files. I want to find all the files that DO NOT contain the string "speedup" so I successfully used the following command:

grep -iL speedup *

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!