Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Recently I received this find one-liner, but I'm not able to explain where the difference of the below two comes from:

Example 1

[root@centos share]# find . -exec grep -i "madis" {} /dev/null \;

./names:Madison Randy:300:Product Development

Example 2

[root@centos share]# find . -exec grep -i "madis" {} \;

Madison Randy:300:Product Development

As you can see, in the first one there is the specific file this string derives from and so far I'm really not able to find out why this is happening.

share|improve this question
add comment

3 Answers 3

You are telling grep to search 2 locations. grep only shows the full location if multiple locations are searched.

For example

touch /tmp/herp /tmp/derp
cd /tmp
echo "foo" > herp
echo "foo" > derp

Notice how if I search just 1 file, grep omits the file name

grep -i "foo" /tmp/herp
foo

But if I specify multiple search locations, grep says where it found each match

grep -i "foo" herp derp
/tmp/derp:foo
/tmp/herp:foo

Adding the /dev/null is it tricking grep into printing out the full path, by providing 2 arguments.

share|improve this answer
1  
+1 but you forgot to mention the "obvious": "The reason the added file is /dev/null is to be sure that whatever is grep-ed won't be found in the (empty) /dev/null file, so only the correct locations are outputed" –  Olivier Dulac Feb 17 at 9:24
    
But also, by searching /dev/null you don't waste any time seaching through a non-empty dummy file. And finally, the intent of searching /dev/null is obvious to those familiar with this idiom. –  alexis Feb 17 at 12:10
add comment

man grep:

-H, --with-filename

Print the file name for each match. This is the default when there is more than one file to search.

The difference results from grep being called with one or two file arguments in the two cases. Instead of adding /dev/null you could call grep with the argument -H. Maybe the /dev/null behaviour is more widely supported.

share|improve this answer
3  
grep -H is not portable -- the /dev/null trick works without GNU grep. –  Chris Down Feb 17 at 2:19
add comment

First example is equivalent to running grep over two files for each file found as a result of the find expression. For example, if find finds three files a.txt, b.txt and c.txt then grep will run as

grep -i "madis" a.txt /dev/null
grep -i "madis" b.txt /dev/null 
grep -i "madis" c.txt /dev/null

To which grep will show the filename for which the output matches. Since nothing will match the /dev/null, it is guaranteed that the filename of the first file will be printed if it matches.

Whereas, the second example is equivalent of

grep -i "madis" a.txt
grep -i "madis" b.txt 
grep -i "madis" c.txt 

In which case the filename will not be printed for matches as there is just one argument.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.