3

I'm trying to pipe the output of a grep search into the input of another grep. Such as:

grep search_query * | grep -v but_not_this

But the second grep is not using the output of the previous search. It looks like the second grep is just using * instead. For example,

grep lcov *                                                                                          
tst/bits/Module.mk:21:$(call func_report_lcov)
tst/drivers/Module.mk:27:$(call func_report_lcov)

But when I want to filter out the results containing "call",

grep lcov * | grep -v call
...

Grep gives me every single line in my workspace that doesn't contain "call".

Environment Info:

  • This is happening in both bash and fish
  • I have aliased the grep command like so alias grep='grep -nR --color=always'

Anything else I might be missing?

  • 2
    grep does not descend into subdirectories without the -r/-R option. Do you have a function or script named grep? What does type -a grep show (in bash)? – glenn jackman Feb 14 '19 at 22:02
7

The alias is what is causing it. From man grep, the -R option causes grep to "read all files under each directory, recursively". Hence, the part after the pipe ignores the output from the first grep, and instead greps through all files recursively from the current directory.

You can bypass the alias and use vanilla grep with \grep. Hence the following should give you what you expect.

grep lcov * | \grep -v call

However, I personally think that putting -R in the alias is confusing.

| improve this answer | |
  • 5
    The main issue here is that GNU grep, when using -R and when not given a filename operand, will act recursively on the contents of the current directory. Other grep implementations don't use . as the default file operand when -R is used and no file operand is given (OpenBSD grep, for example, complains with grep: warning: recursive search of stdin). – Kusalananda Feb 14 '19 at 22:25
  • In a script you could use /bin/grep or $(which grep) instead to make sure there is no alias set. – Freddy Feb 15 '19 at 0:05
  • @Freddy Generally scripts wouldn't source .bashrc. – Sparhawk Feb 15 '19 at 0:09
  • @Sparhawk Oh yes, how true. – Freddy Feb 15 '19 at 0:16
  • It's not confusing, it's wacky – n.caillou May 27 '19 at 1:43
-1

Interesting. This appears to be correct, looks like the devil's in the details.

grep "search_query" *

could be different than

grep search_query *

which could be different again from

grep 'search_query' *

Try this:

grep search_query * > /tmp/foo
grep -v but_not_this /tmp/foo

Does the file /tmp/foo contain what you want?
Does grep -v but_not_this give the answer you want?
replace grep with \grep to unalias it it and see if that works.

| improve this answer | |
  • Why "could be different"? All the three commands are the same, right? What difference does single/double-quoting make here? – Sparhawk Feb 14 '19 at 22:27
  • It has to do with substitutions. If you are using $ or special characters. Double quotes mean "Substitute Now." Single quotes mean 'Let the program do the substitution.' Suppose I set my_var to Scottie. grep "$my_var" foo becomes grep Scottie foo But grep '$my_var' foo looks for the word $my_var in the file foo – Scottie H Feb 14 '19 at 22:36
  • Yes, but in the question it's just a string lcov. – Sparhawk Feb 15 '19 at 0:09
  • Have you triedto unalias both greps? useing the backslash on BOTH greps? Or unaliasing the grep completely <br> If you send the first gerp to a file, does that file contain what you expect?<br> If rou run the second grep on the file, do you get the correct result? – Scottie H Feb 15 '19 at 1:17
  • Because you have -R in the grep, you are searching EVER non-hidden file in your current directory and EVERY non-hidden SUBdirectory. To see what I mean, run this command: ls -R * Are ALL of those the files you want to grep? – Scottie H Feb 15 '19 at 1:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.