Functionally (in terms of output), those two are the same. The first one actually creates a separate process cat
which simply send the contents of the file to standard output, which shows up on the standard input of the grep
, because the shell has connected the two with a pipe.
In that sense grep regex <filename
is also equivalent but with one less process.
Where you'll start seeing the difference is in variants when the extra information (the file names) is used by grep
, such as with:
grep -n regex filename1 filename2
The difference between that and:
cat filename1 filename2 | grep -n regex
is that the former knows about the individual files whereas the latter sees it as one file (with no name).
While the former may give you:
filename1:7:line with regex in 10-line file
filename2:2:another regex line
the latter will be more like:
7:line with regex in 10-line file
12:another regex line
Another executable that acts differently if it knows the file names is wc
, the word counter programs:
$ cat qq.in
1
2
3
$ wc -l qq.in # knows file so prints it
3 qq.in
$ cat qq.in | wc -l # does not know file
3
$ wc -l <qq.in # also does not know file
3