RvPr
RvPr

Reputation: 1164

Grep: Recursive option produces unexpected behavior when fed pipe-input

I've been using this utility successfully for many years, in many environemnts. But I'm noticing that on one particular environment, it produces very unexpected results.

grep -r 'search-term1' . | grep 'search-term2'

The above code greps recursively for all instances of search-term1, in the current-dir. The results are then piped to another grep, which selects only those lines that also contain search-term2. This works exactly as I would expect.

grep -r 'search-term1' . | grep -r 'search-term2'

The only difference in the above code is that the -r recursive flag in specified in both grep commands. I would expect the behavior to not change for this particular case. After all, the input to the 2nd grep is a pipe-input, and there's nothing further to be found recursively.

I have been using the command successfully, for many years, in many different environments (both unix and mac-os). However, the most recent environment that I started working in (unix), breaks the above behavior. The second piped grep searches for all instances of search-term2, not only in the piped-input, but also all files in my current directory. Because of this, instead of getting only results that contain both search-terms, I get all results in current-dir that contain the 2nd search term.

Is there any reason why this one particular environment produces this odd behavior? Is there any way I can avoid this, while still preserving the -r flag?


FAQ:

Q: Why am I using the -r flag on a piped input?

Ans: I actually have grep saved as an alias, with many different options and flags that I always want to use as a default. The recursive flag is one of them. I would like to always use this alias, instead of having to type out all the flags every time.

Q: If you want to search for all instances matching both search terms, why not do (insert-superior-method-here) instead?

Ans: You're probably right. I'm sure there are things I can change in my usual habits that would workaround this issue. However, as intellectual curiosity, I would like to find out why recursive-greps-on-pipes work as intended on most environments, but not all, and if that can somehow be resolved.

Upvotes: 4

Views: 380

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 81012

The -r flag to grep changed in grep version 2.11 (release notes to implicitly use the working directory as the input if no file arguments are given.

If no file operand is given, and a command-line -r or equivalent option is given, grep now searches the working directory.

You aren't giving the second grep any file arguments so it defaults to the current directory despite there being pipe input.

Try grep -r 'search-term1' . | grep -r 'search-term2' - as a workaround.

grep -r 'search-term1' . | grep -r -d skip 'search-term2' may also work around the problem.

Upvotes: 4

Related Questions