Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Sep 2003 17:37:54 -0400 (EDT)
From:      Mikhail Teterin <mi@aldan.algebra.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/57024: a new option for xargs(1) -- only treat \n as separators
Message-ID:  <200309192137.h8JLbsIs061221@250-217.customer.cloud9.net>
Resent-Message-ID: <200309192140.h8JLeDVs052265@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         57024
>Category:       bin
>Synopsis:       a new option for xargs(1) -- only treat \n as separators
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 19 14:40:13 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Mikhail Teterin
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
Virtual Estates, Inc.
>Environment:
System: FreeBSD mi.us.murex.com 5.1-CURRENT FreeBSD 5.1-CURRENT #5: Wed Sep 10 16:35:59 EDT 2003 root@mi.us.murex.com:/misha/obj/misha/src/sys/Misha-g i386

>Description:

	While the -0 option provides the ultimate solution for handling
	unusual characters in file-names, it requires cooperation from
	the input generator (such as find(1)).

	Sometimes, the potential input for xargs(1) is generated by a
	non-cooperating utility, which does not have the find(1) -print0
	equivalent. Output of ``tar -t'' is one example.

	The '\n' character, however, happens very rarely in the filenames.
	It would be of great convenience to be able to specify it as the
	only separator, for it does not require modifications to the input.

		find .... | xargs -N ...

	will work as good as

		find .... -print0 | xargs -0 ...

	as long as there are no filenames with embedded \n.

>How-To-Repeat:

		tar -t some.tar | xargs ls -l

	would break if the archive has files with tabs or spaces in
	their names. While modifying tar is an option, the proposed
	new flag will solve the problem for almost everybody:

		tar -t some.tar | xargs -N ls -l

>Fix:

	This would be another non-standard option and the patch
	below documents it as such.

Index: xargs.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/xargs/xargs.1,v
retrieving revision 1.30
diff -U2 -r1.30 xargs.1
--- xargs.1	21 May 2003 21:07:28 -0000	1.30
+++ xargs.1	19 Sep 2003 21:33:31 -0000
@@ -46,5 +46,5 @@
 .Sh SYNOPSIS
 .Nm
-.Op Fl 0opt
+.Op Fl 0Nopt
 .Op Fl E Ar eofstr
 .Oo
@@ -99,4 +99,11 @@
 function in
 .Xr find 1 .
+.It Fl N
+Change
+.Nm
+to only treat newlines as separators. This is not as comprehensive as the
+.Fl 0
+option above, but can be useful if the input contains one argument per line
+as is often the case.
 .It Fl E Ar eofstr
 Use
@@ -295,5 +302,5 @@
 compliant.
 The
-.Fl J , o , P
+.Fl J , N, o , P
 and
 .Fl R
Index: xargs.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/xargs/xargs.c,v
retrieving revision 1.54
diff -U2 -r1.54 xargs.c
--- xargs.c	13 Jun 2003 17:05:41 -0000	1.54
+++ xargs.c	19 Sep 2003 21:33:31 -0000
@@ -81,5 +81,5 @@
 static const char *eofstr;
 static int count, insingle, indouble, oflag, pflag, tflag, Rflag, rval, zflag;
-static int cnt, Iflag, jfound, Lflag, wasquoted, xflag;
+static int cnt, Iflag, jfound, Lflag, Nflag, wasquoted, xflag;
 static int curprocs, maxprocs;
 
@@ -125,5 +125,5 @@
 	}
 	maxprocs = 1;
-	while ((ch = getopt(argc, argv, "0E:I:J:L:n:oP:pR:s:tx")) != -1)
+	while ((ch = getopt(argc, argv, "0NE:I:J:L:n:oP:pR:s:tx")) != -1)
 		switch(ch) {
 		case 'E':
@@ -176,4 +176,7 @@
 			zflag = 1;
 			break;
+		case 'N':
+			Nflag = 1;
+			break;
 		case '?':
 		default:
@@ -183,4 +186,6 @@
 	argv += optind;
 
+	if (zflag && Nflag)
+		errx(1, "-0 and -N are mutually exclusive");
 	if (!Iflag && Rflag)
 		usage();
@@ -269,5 +274,5 @@
 	case '\t':
 		/* Quotes escape tabs and spaces. */
-		if (insingle || indouble || zflag)
+		if (insingle || indouble || zflag || Nflag)
 			goto addch;
 		goto arg2;
@@ -353,5 +358,5 @@
 		break;
 	case '\'':
-		if (indouble || zflag)
+		if (indouble || zflag || Nflag)
 			goto addch;
 		insingle = !insingle;
@@ -359,5 +364,5 @@
 		break;
 	case '"':
-		if (insingle || zflag)
+		if (insingle || zflag || Nflag)
 			goto addch;
 		indouble = !indouble;
@@ -365,5 +370,5 @@
 		break;
 	case '\\':
-		if (zflag)
+		if (zflag || Nflag)
 			goto addch;
 		/* Backslash escapes anything, is escaped by quotes. */
@@ -600,5 +605,5 @@
 {
 	fprintf(stderr,
-"usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
+"usage: xargs [-0Nopt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]\n"
 "             [-L number] [-n number [-x]] [-P maxprocs] [-s size]\n"
 "             [utility [argument ...]]\n");
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200309192137.h8JLbsIs061221>