From owner-freebsd-hackers Fri May 11 18: 3:33 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from bazooka.unixfreak.org (bazooka.unixfreak.org [63.198.170.138]) by hub.freebsd.org (Postfix) with ESMTP id 633C637B43C; Fri, 11 May 2001 18:03:20 -0700 (PDT) (envelope-from dima@unixfreak.org) Received: from spike.unixfreak.org (spike [63.198.170.139]) by bazooka.unixfreak.org (Postfix) with ESMTP id B3B893E0B; Fri, 11 May 2001 18:03:19 -0700 (PDT) To: hackers@freebsd.org Cc: gad@freebsd.org Subject: xargs(1) "replstr" patch Date: Fri, 11 May 2001 18:03:19 -0700 From: Dima Dorfman Message-Id: <20010512010319.B3B893E0B@bazooka.unixfreak.org> Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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