Add a -J replstr option that allows the user to tell xargs to insert

the data read from standard input at a specific point in the command
line arguments rather than at the end.

Submitted by:	dd, gad
Reviewed by:	gad, brian
This commit is contained in:
Dima Dorfman 2001-05-15 00:31:19 +00:00
parent 70e48365cc
commit 8d904f1537
2 changed files with 68 additions and 6 deletions

View File

@ -36,7 +36,7 @@
.\" @(#)xargs.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
.Dd June 6, 1993
.Dd May 7, 2001
.Dt XARGS 1
.Os
.Sh NAME
@ -45,6 +45,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl 0
.Op Fl J Ar replstr
.Oo
.Fl n Ar number
.Op Fl x
@ -91,6 +92,38 @@ This is expected to be used in concert with the
.Fl print0
function in
.Xr find 1 .
.It Fl J Ar replstr
If this option is specified,
.Nm
will use the data read from standard input to replace the first occurrence of
.Ar replstr
instead of appending that data after all other arguments.
This option will not effect how many arguments will be read from input
.Pq Fl n ,
or the size of the command(s)
.Nm
will generate
.Pq Fl s .
The option just moves where those arguments will be placed in the command(s)
that are executed.
The
.Ar replstr
must show up as a distinct
.Ar argument
to
.Nm .
It will not be recognized if, for instance, it is in the middle of a
quoted string.
Furthermore, only the first occurrence of the
.Ar replstr
will be replaced.
For example, the following command will copy the list of files and
directories which start with an uppercase letter in the current
directory to
.Pa destdir :
.Pp
.Dl /bin/ls -1d [A-Z]* | xargs -J [] cp -rp [] destdir
.Pp
.It Fl n Ar number
Set the maximum number of arguments taken from standard input for each
invocation of the utility.
@ -173,6 +206,11 @@ The
utility is expected to be
.St -p1003.2
compliant.
The
.Fl J
option is a non-standard
.Fx
extention which may not be available on other operating systems.
.Sh BUGS
If
.Ar utility

View File

@ -70,10 +70,15 @@ main(argc, argv, env)
{
register int ch;
register char *p, *bbp, *ebp, **bxp, **exp, **xp;
int cnt, indouble, insingle, nargs, nflag, nline, xflag, wasquoted;
char **av, *argp, **ep = env;
int cnt, jfound, indouble, insingle;
int nargs, nflag, nline, xflag, wasquoted;
char **av, **avj, *argp, **ep, *replstr;
long arg_max;
ep = env;
jfound = 0;
replstr = NULL; /* set if user requests -J */
/*
* POSIX.2 limits the exec line length to ARG_MAX - 2K. Running that
* caused some E2BIG errors, so it was changed to ARG_MAX - 4K. Given
@ -96,8 +101,11 @@ main(argc, argv, env)
nline -= strlen(*ep++) + 1 + sizeof(*ep);
}
nflag = xflag = wasquoted = 0;
while ((ch = getopt(argc, argv, "0n:s:tx")) != -1)
while ((ch = getopt(argc, argv, "0J:n:s:tx")) != -1)
switch(ch) {
case 'J':
replstr = optarg;
break;
case 'n':
nflag = 1;
if ((nargs = atoi(optarg)) <= 0)
@ -144,6 +152,13 @@ main(argc, argv, env)
else {
cnt = 0;
do {
if (replstr && strcmp(*argv, replstr) == 0) {
jfound = 1;
argv++;
for (avj = argv; *avj; avj++)
cnt += strlen(*avj) + 1;
break;
}
cnt += strlen(*bxp++ = *argv) + 1;
} while (*++argv);
}
@ -211,6 +226,10 @@ arg2:
if (xp == exp || p > ebp || ch == EOF) {
if (xflag && xp != exp && p > ebp)
errx(1, "insufficient space for arguments");
if (jfound) {
for (avj = argv; *avj; avj++)
*xp++ = *avj;
}
*xp = NULL;
run(av);
if (ch == EOF)
@ -253,6 +272,10 @@ addch: if (p < ebp) {
if (xflag)
errx(1, "insufficient space for arguments");
if (jfound) {
for (avj = argv; *avj; avj++)
*xp++ = *avj;
}
*xp = NULL;
run(av);
xp = bxp;
@ -307,7 +330,8 @@ run(argv)
static void
usage()
{
(void)fprintf(stderr,
"usage: xargs [-0] [-t] [-n number [-x]] [-s size] [utility [argument ...]]\n");
fprintf(stderr,
"usage: xargs [-0t] [-J replstr] [-n number [-x]] [-s size]\n"
" [utility [argument ...]]\n");
exit(1);
}