[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: GREP



Damian Menscher <menscher@uiuc.edu> wrote:
>On Fri, 20 Oct 2000, Erik Steffl wrote:
>>   yes, that's true, are you asking what the '?' is or are you just
>> stating the fact? anyway, the other command is find, see manpages for
>> find and grep for more info. find is the one that finds file (based on
>> name, time last accessed, type and various other criteria), grep
>> searches the files for string (regular expression). xargs is often
>> useful in commands like this:
>> 
>>   find / -name '*.h' -print | xargs grep '[sf]printf'
>
>Just curious, but is this any better/worse than doing a
>
>find / -name '*.h' -exec grep '[sf]printf' {} \;
>
>My way seems more straightforward, but I'm not sure about differences in
>processing time, when the first match would be found, etc.

'find | xargs' is almost always better. 'find -exec' will fork the named
program once for each file found, which may well consume a lot of CPU
time, particularly on anything starting 'find /'.

As a demonstration, have a look at the first few lines of the output of
the following commands:

[cjw44@riva ~]$ find / -type f -exec echo {} \;                
/var/cache/apt/pkgcache.bin
/var/cache/apt/srcpkgcache.bin
/var/cache/apt/archives/lock
/var/cache/man/cat1/ytalk.1.gz
/var/cache/man/cat1/ln.1.gz
/var/cache/man/cat1/dh_perl.1.gz
/var/cache/man/cat1/deborphan.1.gz
/var/cache/man/cat1/rnews.1.gz
/var/cache/man/cat1/write.1.gz
/var/cache/man/cat1/python.1.gz
[...]

[cjw44@riva ~]$ find / -type f | xargs echo
/var/cache/apt/pkgcache.bin /var/cache/apt/srcpkgcache.bin /var/cache...

I've chopped off the rest of this line for clarity, but you can try it
for yourself. The command executed with -exec gets one argument each
time it's run, while the command executed with xargs gets as many as
will fit onto one command line. Normally this shouldn't have any impact
on when the first match with grep will be found.

'find -exec' also appears to have poor behaviour when piped to something
else; SIGPIPE doesn't seem to be trapped properly (and it's probably
difficult to do it properly, if I'm guessing right), so you get a lot of
errors like "find: grep terminated by signal 13" when you try to pipe
the output to e.g. 'head'.

Of course, in order to make good use of xargs, the program being
executed needs to take an arbitrary number of filename arguments at the
end of its command line. You can use the -i option to insert an argument
somewhere else in the command line, but then you're back to forking a
copy of the program each time. There are lots of other options for more
specialized uses. Fortunately, most of the standard Unix filter programs
have a command-line syntax suitable for use with xargs.

-- 
Colin Watson                                     [cjw44@flatline.org.uk]



Reply to: