Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!rutgers!mcdchg!illusion!marcus From: marcus@illusion.uucp (Marcus Hall) Newsgroups: comp.unix.questions Subject: Re: grep Keywords: grep, recursive Message-ID: <1991Apr16.185820.7920@illusion.uucp> Date: 16 Apr 91 18:58:20 GMT References: <1991Apr14.214414.9815@hellgate.utah.edu> <4037@risky.Convergent.COM> Reply-To: marcus@illusion.UUCP (Marcus Hall) Organization: Magic Numbers Software, Bloomingdale, IL Lines: 42 In article <4037@risky.Convergent.COM> sundrag@risky.Convergent.COM (Sundaraswaran Gopalakrishnan) writes: >In article <1991Apr14.214414.9815@hellgate.utah.edu>, mmoore%hellgate.utah.edu@cs.utah.edu (Michael Moore) writes: >> Does anyone know if there is an easy way to recursively search for a >> pattern down the entire file tree of a directory? > >You can do the following : >find / -print | xargs grep >or, >find / -name "*.c" -print | xargs grep > >xargs constructs the argument list from its input and 'll >apply grep to each argument ( which is different from just >"find / -print | grep ", which 'll look for a *file* >that matches ) > >Sundar, Unisys Unfortunately, grep causes a slight problem with this. The problem is that if grep has two or more file arguments it prints the file name and a colon before the matched lines. If it has a single file argument, it does not. Now, xargs collects some number of lines from stdin and gives them to grep as file arguments (or so grep interprets them). After potentially kicking off several greps, if there is only one line left on xarg's stdin, it will kick off a new grep with a single argument. If this grep matches any lines, it will not output the file name, just the matched lines. Thus, it will be unclear just where these lines came from! There is no option to force grep to output the file name, but one trick that can be used to do this is to always give grep an extra argument. If this is "/dev/null", then grep cannot possibly match anything in it, so it is effectively a noop, but it does force grep to output file names. Thus, the commands from above should be written as: find ... -type f -print | xargs grep /dev/null - or - find ... -type f -name "*.c" -print | xargs grep /dev/null (The "-type f" is there because you probably don't want to do grep through directories and especially you do not want to do it through /dev files!!) marcus hall