Friday, January 25, 2013

Basic GNU: using find and grep to search over a list of files

GNU find and GNU grep are two of the most useful entities in the Linux system administrator's toolbox. But learning to use them can be tiresome.

Often when I am using grep to search files for a string (regex), but get too much extraneous information. Something like this:

# grep "searchstring" /etc/*
grep: ConsoleKit: Is a directory
grep: ImageMagick: Is a directory
... 49 more lines, all complaining about the same thing ...

One obvious way to narrow this down is to simply append 2>/dev/null, which sends all the errors to the bit bucket:
# cd /etc
# echo "searchstring" >blogtest
# grep "searchstring" *
blogtest:searchstring
# rm blogtest

Another way is to use GNU find to generate a list of files, and feed that to GNU grep. This is a very powerful technique that requires some knowledge of GNU find. That's easy, right? Just read the manpage . . . uh, yeah:
# man find | col -b | wc --lines
1212

Until we find time to study that, here's a simple example:
# echo "searchstring" >blog\ test
# find . -type f | xargs grep searchstring
grep: ./blog: No such file or directory
grep: test: No such file or directory

Hmm. This is the kind of thing that gives find a bad rap. But at least we now understand why we need -print0: it makes find generate NULL-terminated strings.
# find . -type f -print0 | xargs -0 grep searchstring
./blog test:searchstring

Here's another way to do it:
# find . -type f -exec grep -H searchstring {} \;
./blog test:searchstring

Oh, and by the way, don't forget to clean up:
# rm blog\ test

No comments:

Post a Comment