XAPPLY(1)

NAME
xapply - extended apply and xargs replacement

SYNOPSIS
xapply -f [-nv] [-count] [-a c] [-i input] [-p pad] [-Pjobs] [-S shell] cmd [files]
xapply [-nv] [-count] [-a c] [-i input] [-Pjobs] [-S shell] cmd [args]
xapply -h
xapply -V

DESCRIPTION

Extended apply is intended to be a complete replacement for the apply and xargs commands. In the normal mode xapply emulates the best features of apply (substitutes limited percent escapes to form and execute shell commands). Under -f it emulates a xargs-like processor.

Unlike xargs this program deals in fixed argument lists. Each positional parameter (or input line) is treated as a single argument for the expanded command (embedded blanks, tab, quotes and the like are not special). If a variable argument list is required it may be built with fmt or adjust (or any other text processor) and passed in pre-formatted (see BUGS).

The fixed argument list is built from a hunk of count parameters from the command line. These parameters are usually interpreted as fixed strings, but under -f they are taken as files whose lines are each taken sequentially as arguments.

The pointer positional parameter cmd is the template command to control each task. In this template each occurance of the escape character c, percent (%) by default, followed by a digit ([1-9]) is replaced by the current argument for that slot. If no such expansions occur in a template the whole argument list is catenated on the end of cmd (prefixed by a blank when needed).

To extend this a bit we also allow curly braces to enclose larger integer value (e.g. %{15}) as make(1) does for macro names. In addition the value zero (in either case) is taken to mean no expansion is expected; this supresses the default catenation of the whole argument list as well.

To keep up with more complex structures a final form is allowed to extract subfields from input parameters:

    %[param separator field ]

The positional parameter param is broken into fields at the character separator. The resultant field is the substituted. The special field dollar sign ($) is taken as the last field.

When a literal blank is used as the separator it matches any number of white space characters. The universal escape character backslash (\) may be used to quote any of blank, backslash, close bracket, or any digit to supress its special meaning. Additional separator and field pairs may be used to further limit the expansion.

OPTIONS

-count
    Each expanded command requires count of arguments.

-a c
    Change the escape character from percent (%) to c.

-f  Arguments are read one per line from the input files. Each file is opened and scanned for arguments (which are only separated by newlines). Note that all references to the stdin ("-") stream share the stream: that is, arguments are taken round-robin from each active reference. Files are hunked together by the -count option as fixed parameters would be.

-h  Print a help message.

-i input
    Under -f sub-tasks competing for input with xapply lead to madness. Xapply opens all sub-tasks stdin to a shared stream from Input. Under -f this deafults to /dev/null.

-n  Do not execute commands, trace only. (Implies -v.)

-p pad
    Files with inadequate length are padded with this token.

-Pjobs
    Number of tasks to run in parallel. Xapply tries to keep at most jobs processes running in parallel. If the environment variable PARALLEL is set then it is read for a default value. xapply waits for all tasks to finish before it exits.

-S shell
    Specify shell to run tasks under. Xapply looks for the environment variable SHELL or uses the built-in default /bin/sh. In any case shell must take -c as sh(1) does.

-v  Be verbose. Echo shell commands to stdout.

-V  Show version information.

EXAMPLES

xapply '(cd %1 && make all)' */
    Change context to each directory in the current directory in turn and run make all.

xapply -f 'diff %1 ../version5/%1' manifest | more
    Compare the files in manifest to the ones with the same name in ../version5

xapply -p/dev/null -f 'diff %1 %2' manifest1 checklist1
    Compare (with diff) each file in manifest1 to the same file in checklist1. Substitute /dev/null for missing files on the end. {This is only useful if the input files are known to have the arguments in a stable order.}

xapply 'indent' *.c
    Run indent for each C source file in the current directory.

find ~ksb/bin -type f ! -perm -111 -print | xapply -f -v 'chmod a+x' -
    Find plain files in my bin which are not executable by all, let xapply try to fix each (and show me the progress).

find */ -... | fmt 960 1024 | xapply -f -i /dev/tty 'vi' -
    Run vi on blocks of files from the find command. This is so clever.

find ... | xapply -f -5 -i /dev/tty 'vi' - - - - -
    Edit five files at a time (until the last edit).

xapply -fn "" /etc/passwd
    A slower version of cat(1).

tr ':' '\012' < /etc/passwd | xapply -7 -nf 'chown %1 %6' - - - - - - -
    Shows how to get the fields of the password file into xapply escapes.

xapply -V
    Output xapply's version information.

xapply '[ -d %1/RCS ] || echo %1' */
    Output each subdirectory that does not have an RCS cache.

xapply -f '[ -f %1 ] && echo %1' List | ...
    Output the pathnames from List that presently exist (note the inverse could be accomplished as well).

BUGS

Some more escapes might be useful. (Of course I'd say that.)

Should have a filter buddy that knows xargs's input rules to convert a input stream to our style. But then again who uses the broken xargs quoting rules?

Modern fmt is too smart and won't work on file names that start with dot (it thinks they are nroff directives). This crosses that fine line I always talk about. One can use a sed filter, viz.
    sed -e 's,^.//*,,' | fmt ...
to repair the damange.

AUTHOR
Kevin Braunsdorf
DSPD UNIX Support
ksb@fedex.com

SEE ALSO
sh(1), cat(1), apply(1), xargs(1), fmt(1) or adjust(1), make(1), find(1), vi(1), sed(1)