Prescription
One simple rewrite command in question:
grep "word1" logs | grep "word2"
The first grep finds lines with "word1" from the "logs" file, and then passes them to the second grep , which looks for lines containing "word2".
However, there is no need to use two commands. You can use extended grep ( grep -E or egrep ):
grep -E 'word1.*word2|word2.*word1' logs
If you know that the word "word1" will precede "word2" on the line, you don't even need alternatives, and regular grep will do:
grep 'word1.*word2' logs
Variants of the "one command" have the advantage that only one process is running, so lines containing "word1" should not be piped to the second process. How important this is depends on how big the data file is and how many lines match "word1". If the file is small, performance is unlikely to be a problem, and the execution of two commands will be fine. If the file is large, but only a few lines contain the word "word1", there will not be much data on the pipe, and the use of two commands is fine. However, if the file is huge, and the word "word1" is common, you can transfer important data over the channel, where one command avoids this overhead. In contrast, regex is more complex; you may need to compare it to find out which is best, but only if performance really matters. If you run two commands, you should strive to select a less frequently occurring word in the first grep in order to minimize the amount of data processed by the second.
Diagnostics
Initial script:
grep -c "word1" | grep -r "word2" logs
This is an odd sequence of commands. The first grep will count the number of occurrences of the word "1" on its standard input and print this number on its standard output. Until you specify EOF (for example, by typing Control-D ), it will sit there, waiting for you to type something. The second grep performs a recursive search for "word2" in the files under the logs directory (or, if it is a file, in the logs file). Or, in my case, this will not work, because there is neither a file nor a directory called logs where I run the pipeline. Please note that the second grep does not read its standard input at all, so the channel is superfluous.
With Bash, the parent shell waits until all processes in the pipeline exit, so it sits waiting for grep -c finish, which it wonβt do until you specify EOF. Therefore, your code seems to be stuck. With Heirloom Shell, the second grep terminates and terminates, and the shell requests again. Now you have two processes: the first grep and the shell, and they both try to read from the keyboard, and it is not determined which one gets any input line (or any specified EOF indication).
Note that even if you entered the data as input for the first grep , you would only get lines containing "word2" shown in the output.
Footnote:
At one point, the answer is used:
grep -E 'word1.*word2|word2.*word1' "$@" grep 'word1.*word2' "$@"
This triggered the comments below.