What's the difference between grep -r and -R
"Being on the command line" refers to the arguments passed to grep. If you give a symbolic link as an argument to grep -r
it follows it. However, if grep -r
encounters a symbolic link while traversing a directory it does not follow it (in contrast to grep -R
which does).
Imagine you have a directory with a bunch of files in it, including one containing a symbolic link to ..
(the parent directory):
$ ls -la
total 0
drwxr-xr-x 2 aw aw 47 Mar 31 16:05 .
drwxr-xr-x 3 aw aw 27 Mar 31 16:04 ..
-rw-r--r-- 1 aw aw 0 Mar 31 16:05 bar
-rw-r--r-- 1 aw aw 0 Mar 31 16:05 baz
lrwxrwxrwx 1 aw aw 2 Mar 31 16:04 foo -> ..
-rw-r--r-- 1 aw aw 0 Mar 31 16:05 quux
$
Then,
grep -r foobar .
will only grep the files inside this directory,grep -r foobar foo
will grep the files in the parent directory (..
) (following the symlink given as an argument),grep -R foobar .
will also grep the files in the parent directory (following the symlink not given as an argument but found while traversing the current directory).
If you check also man grep
:
-r, --recursive
Read all files under each directory, recursively, following symbolic links only if they are on the command line. This is equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
See an example:
We create in /test
a file with the content
$ cat /test/a
Ping info
Hello
And then I create a symlink:
$ ln -s /test/a /test/dir/b
So that it looks like:
$ ls -l /test/dir
b -> ../a
And now we grep
:
$ grep -r Ping /test/dir/* #does NOT follow the symlink to ../a
a:Ping info
$ grep -R Ping /test/dir/* #DOES follow the symlink to ../a
a:Ping info
dir/b:Ping info