To view a list of files that meet certain criteria, simply run your file viewing program with the file names as arguments. Shells substitute a command enclosed in backquotes with its output, so the whole command looks like this:
less `find /usr/include -name '*.h' | xargs grep -l mode_t`
You can edit those files by giving an editor name instead of a file viewing program:
emacs `find /usr/include -name '*.h' | xargs grep -l mode_t`
Because there is a limit to the length of any individual command line,
there is a limit to the number of files that can be handled in this way.
We can get around this difficulty by using xargs
like this:
find /usr/include -name '*.h' | xargs grep -l mode_t > todo xargs --arg-file=todo emacs
Here, xargs
will run emacs
as many times as necessary to
visit all of the files listed in the file todo. Generating a
temporary file is not always convenient, though. This command does
much the same thing without needing one:
find /usr/include -name '*.h' | xargs grep -l mode_t | xargs sh -c 'emacs "$@" < /dev/tty' Emacs
The example above illustrates a useful trick; Using sh -c
you
can invoke a shell command from xargs
. The $@
in the
command line is expanded by the shell to a list of arguments as
provided by xargs
. The single quotes in the command line
protect the $@
against expansion by your interactive shell
(which will normally have no arguments and thus expand $@
to
nothing). The capitalised ‘Emacs’ on the command line is used as
$0
by the shell that xargs
launches.
Please note that the implementations in GNU xargs
and at least BSD
support the ‘-o’ option as extension to achieve the same, while the
above is the portable way to redirect stdin to /dev/tty.