Date: Fri, 11 May 2001 18:03:19 -0700 From: Dima Dorfman <dima@unixfreak.org> To: hackers@freebsd.org Cc: gad@freebsd.org Subject: xargs(1) "replstr" patch Message-ID: <20010512010319.B3B893E0B@bazooka.unixfreak.org>
next in thread | raw e-mail | index | archive | help
Folks,
The attached patch adds a "replacement string" feature to xargs(1).
There's a full description in the man page update (also attached), but
the following should demonstrate the new functionality:
dima@spike% ./xargs -J [] echo CMD LINE [] ARGS < test
CMD LINE this is the contents of the test file ARGS
dima@spike% ./xargs -J [] echo CMD [] LINE ARGS < test
CMD this is the contents of the test file LINE ARGS
dima@spike% ./xargs -J [] echo [] CMD LINE ARGS < test
this is the contents of the test file CMD LINE ARGS
This is similar to, but not identical to, the -I option described in
SUSv2. The latter allows the replstr ("[]" above) to be attached to
other arguments, and appear multiple times. Furthermore, it implies
'-n 1'. Although the features are similar, they can solve different
problems; even if -I is implemented later, this (-J) would still be
useful. -J also doesn't have the performance implications attached
with -I.
There was a nice, long thread about this on current a few weeks ago
(topic: "Re: cp -d dir patch for review (or 'xargs'?)"). It was
rather inconclusive, but nobody managed to come up with a way to
*properly* and *easily* imitate this functionality. Writing a script
to do this *properly* (i.e., handle environment growth) isn't as easy
as it sounds (although it's possible, of course).
The patch is a joint effort between myself and Garance Dorsihn (gad).
Comments? Suggestions?
Thanks in advance,
Dima Dorfman
dima@unixfreak.org
Index: xargs.1
===================================================================
RCS file: /st/src/FreeBSD/src/usr.bin/xargs/xargs.1,v
retrieving revision 1.13
diff -u -r1.13 xargs.1
--- xargs.1 2001/05/02 06:41:46 1.13
+++ xargs.1 2001/05/11 23:57:27
@@ -36,7 +36,7 @@
.\" @(#)xargs.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD: src/usr.bin/xargs/xargs.1,v 1.13 2001/05/02 06:41:46 dd Exp $
.\"
-.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 @@
.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 @@
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
Index: xargs.c
===================================================================
RCS file: /st/src/FreeBSD/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.9
diff -u -r1.9 xargs.c
--- xargs.c 1999/08/28 01:07:50 1.9
+++ xargs.c 2001/05/11 23:57:27
@@ -70,10 +70,15 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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);
}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010512010319.B3B893E0B>
