pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
Philip Newton ([personal profile] pne) wrote in [community profile] command_liners 2009-10-07 09:36 am (UTC)

find + xargs are BFF.

Another trick: if your filenames have spaces in them, xargs may not do what you expect. If you have GNU find and xargs, you can get around this with find ... -print0 | xargs -0 ..., which will cause find to separate arguments with null bytes (which can't occur in filenames), so xargs can pick them apart unambiguously.

Two common-ish invocations of find + xargs + grep for me are:

find . -name 'whatever' | xargs grep -l string

for telling me only which files the string appears in, but not listing all the lines that match, and

find . -name 'whatever' | xargs grep string /dev/null

for find the matches but making sure that each matching line has the name of the file at the beginning.

The idea behind the latter is that grep adds the name of the file only if you asked it to search through more than one file (otherwise it thinks that you already know the name, since you just gave that one name to it), and that xargs doesn't tack all the names on the commandline but batches them (subject to the maximum length of the commandline, I think)... so if the batch size happened to be, say, 50, and you had 101 files coming out of find, xargs would call grep three times: with 50, 50, 1 arguments.

So if the match was in the last file output by find, grep would think that it was called with only one argument (which it was) and wouldn't report the filename before the match.

Adding /dev/null to the end of the commandline makes sure that grep will always have at least two files (in the example, grep would see grep string /dev/null lastfilename.txt, and will search both the empty file and the real file.

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting