Why doesn't find's "{}" symbol do what I want?
"find" has a -exec option that will execute a particular commandon all the selected files. Find will replace any "{}" it sees
with the name of the file currently under consideration.
So, some day you might try to use "find" to run a command on
every file, one directory at a time. You might try this:
find /path -type d -exec command {}/\* \;
hoping that find will execute, in turn
command directory1/*
command directory2/*
...
Unfortunately, find only expands the "{}" token when it appears
by itself. Find will leave anything else like "{}/*" alone, so
instead of doing what you want, it will do
command {}/*
command {}/*
...
once for each directory. This might be a bug, it might be a
feature, but we're stuck with the current behaviour.
So how do you get around this? One way would be to write a
trivial little shell script, let's say "./doit", that consists of
command "$1"/*
You could then use
find /path -type d -exec ./doit {} \;
Or if you want to avoid the "./doit" shell script, you can use
find /path -type d -exec sh -c 'command $0/*' {} \;
(This works because within the 'command' of "sh -c 'command' A B C ...",
$0 expands to A, $1 to B, and so on.)
or you can use the construct-a-command-with-sed trick
find /path -type d -print | sed 's:.*:command &/*:' | sh
If all you're trying to do is cut down on the number of times
that "command" is executed, you should see if your system has the
"xargs" command. Xargs reads arguments one line at a time from
the standard input and assembles as many of them as will fit into
one command line. You could use
find /path -print | xargs command
which would result in one or more executions of
command file1 file2 file3 file4 dir1/file1 dir1/file2
Unfortunately this is not a perfectly robust or secure solution.
Xargs expects its input lines to be terminated with newlines, so
it will be confused by files with odd characters such as newlines
in their names.
Home | FAQ |