tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/44246: enhance mv to work better with xargs



> I've taken a look at bin/44246 and attempted to implement an
> enhancement to resolve the PR.

IMO this is not a defect in mv, but a defect in xargs.

mv is (even "mv and cp and ln are") hardly the only case(s) where more
than just appending arguments to a command would be useful.

With my xargs, this would be, eg, "ls -1 | xargs -kX mv X newdir".
Here's the comment header describing the functionality.  I don't expect
NetBSD would want it directly, if only because I doubt NetBSD agrees
with me that the standard-specified xargs behaviour with respect to
whitespace and quoting is a bug or at best a misfeature.  But perhaps
something along the lines of -k and -r could be adopted to fix this
once, at the source of the problem, rather than working around it in a
few of the commonest cases by kludging up other tools.  (For example,
mv -x doesn't permit this, which is relatively common for me:
        ls .. | grep something | xargs -kX mv ../X .
In this case it's not all that hard to adapt by running a similar
command in .., but that's a workaround for this case, not a general
fix.)

Of course, NetBSD is also welcome to the whole thing.  I just don't
expect that to be desired; I can easily make it available if it is.

Here's that comment header.

/*
 * xargs - accumulate arguments for a program
 *
 * xargs reads its standard input and accumulates the strings it gets.
 *  When it has enough, either total length or number of strings, it
 *  executes the program named as its argument.  This is useful for
 *  using programs like rm in conjunction with find:
 *
 *      find / -name \*.CKP -print | xargs rm -f
 *
 * Any options to xargs must of course occur before the name of the
 *  command xargs is to execute.  The first argument not beginning with
 *  a - sign (or being an argument to a flag) indicates the beginning
 *  of the command.
 *
 * The options are:
 *
 *      -l      causes xargs to log the command it is about to execute
 *                to stderr just before executing it.
 *
 *      -n      don't execute the commands.  This is pretty useless
 *                except in conjunction with -l.
 *
 *      -N<n>   tells xargs to fork and exec as soon as it has <n>
 *                arguments accumulated (not counting any on the xargs
 *                command line).  It may still fork/exec earlier than
 *                this.  (In the presence of -n, it doesn't actually
 *                fork and exec.)
 *
 *      -0      causes xargs to break its input into arguments on NULs
 *                rather than newlines.
 *
 *      -f      forces xargs to execute the command at least once, with
 *                no arguments if necessary.
 *
 *      -p<n>   causes xargs to execute <n> commands in parallel.
 *                Normally, once a command is started no further
 *                commands are run until it exits.  With this option,
 *                xargs does not block until <n> commands are running,
 *                and, as soon as any one of them exits, xargs unblocks.
 *
 *      -k<str> indicates that instead of taking the given command and
 *                arguments and appending the arguments derived from
 *                the input, xargs should modify and replicate certain
 *                arguments.  Any argument containing <str> will be
 *                replicated, once per string, as in
 *
 *                      .... | xargs -kX mv dir1/X dir2
 *
 *                which will run commands like
 *
 *                      mv dir1/foo dir1/bar dir1/blee dir2
 *
 *                If -k is not used, the effect is as if it were used
 *                with a string that does not otherwise occur, with one
 *                extra trailing argument, equal to that string, on the
 *                command.
 *
 *      -r<c><s1><c><s2>
 *              indicates that certain argument(s) (or portions
 *                thereof) to the command are to be replicated.  If
 *                <s1> appears as an argument to the command, all
 *                arguments between that and the next argument equal to
 *                <s2> (or the last argument, if no argument equals
 *                <s2>) are replicated, appearing once per string.
 *                (Normally, -k will be used as well, and at least one
 *                of the replicated arguments will include the -k
 *                string, but this does not have to be so.)  If an
 *                argument to the command contains but is not equal to
 *                <s1>, then part of that argument is replicated.
 *                Specifically, everything from immediately after the
 *                <s1>, up to but not including the next <s2> (or the
 *                end of the argument if there is no following <s2>),
 *                is replicated.  If -k is used and the replicated
 *                portion contains the -k string, each copy will have
 *                the -k string replaced as appropriate.  For example,
 *
 *                      xargs -kXX -r/A/B cmd mAjB blivet A -q XX -f mXX B -t
 *
 *                will run commands like
 *
 *                      cmd mjjj blivet -q foo -f mfoo -q bar -f mbar -q blee 
-f mblee -t
 *
 *                while
 *
 *                      xargs -kXX -r/A/B cmd -t mAjXXkB
 *
 *                will run commands like
 *
 *                      cmd -t mjfookjbarkjbleek
 *
 *                Neither <s1> nor <s2> may be zero-length; it is also
 *                an error for the second <c> to be missing.
 *
 * If -k is used, any argument containing the -k string but not under
 *  the influence of -r (either because -r is not given or because the
 *  argument is not bracketed appropriately) will nevertheless be
 *  replicated.
 *
 * If -k is used with a string that can overlap itself (ie, it has a
 *  proper suffix that is also a proper prefix), only nonoverlapping
 *  occurrences found in a simple left-to-right scan are used.  Thus,
 *  for example, with -kXX, an argument 1XXXX2 will generate arguments
 *  such as 1foofoo2 and 1barbar2, even though in a sense there are
 *  *three* occurrences of XX in 1XXXX2.
 *
 * In arguments that are being repeated due to -r, no -r strings are
 *  recognized except for the argument that is equal to the second
 *  string; in particular, arguments that contain but are not equal to
 *  the -r string(s) are not noticed.
 *
 * When the -k and -r strings are such that they can overlap, and an
 *  argument contains overlapping instances, which one is recongized is
 *  unspecified.
 *
 * It is an error for an argument to both contain but be different from
 *  the first -r string and also contain the -k string in a position
 *  where it is not being repeated due to -r.
 *
 * Unlike the "standard" System V xargs, this one doesn't consider a line
 *  containing whitespace as more than one argument.  (I consider this a bug
 *  in the SV xargs; the absence of a flag to fix it is definitely a
 *  misfeature.)
 */

/~\ The ASCII                             Mouse
\ / Ribbon Campaign
 X  Against HTML                mouse%rodents-montreal.org@localhost
/ \ Email!           7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Home | Main Index | Thread Index | Old Index