Your awk example is doing the entire regex search in one pass. For each line of input, if the first, second, and third regex is found, the line will be printed, and you'll see the output essentially immediately (upon processing of the matching line).
Your grep example is using 3 different invocations of grep (one for each regex) to do the same thing, but the output of each invocation becomes the input for the next, which means that each needs to complete before the next has anything to process.
If you had a single 1000 line file and only line 5 matched all three regex, the awk command would give you output after processing the 5th line, before processing the 6th line. Compare that to the piped grep statements. The 1st invocation of grep would find the 5th line and whatever other lines may match the 1st regex, and after processing the 1000th (final) line of input, its output becomes the input to the 2nd invocation of grep. The second invocation of grep processes however many lines the 1st output and outputs the lines that match both the 1st and 2nd regex, which then becomes the input to the 3rd invocation of grep. As the 3rd invocation of grep processes each line, it will output any line that matches its regex.
You can compare the best and worst cases of grep for the above example: if none of the lines match any of the regex except line 5, which matches all 5, then the first grep processes 1000 lines, the second grep processes 1 line, and the third grep processes 1 line: it will process 1002 lines before has any output (best case). If all the lines match the first two regex but only one line matches the third regex, then the piped grep construction will process 1000 + 1000 lines + 5 = 2005 lines before it finds the match on the 5th line and has some output (it will continue to process the remaining 995 lines from the second grep's output, but you won't see any more output because nothing else will match).
Compare that to the awk command, which checks all three regex simultaneously for each line and gives you output after processing the 5th line. The difference will be exaggerated as you check more files simultaneously.
For instance, compare if you see output faster if instead of running the grep command on all files simultaneously as you did above (theoretically, you should, but results may vary depending on distribution of hits throughout your files):
grep -E 'string1|string2' 151103*.log|grep 'string3' | grep string4
you instead run the series of grep commands on each file individually, like this:
for i in 151103*.log;
do grep -E 'string1|string2' $i |grep 'string3' | grep string4;
done
This still won't produce output as quickly as the awk statement, but you may see a difference.
grep
will probably be faster if all patterns are searched for in the same invocation.awk
is a larger program, more code and more features, whilegrep
is smaller in code size and only looking for text patterns in files. It would be interesting if you do that. – RobertL Nov 04 '15 at 15:50