Add 'w' flag to:

Use whitespace (spaces and tabs) as the delimiter.
Consecutive spaces and tabs count as one single field
separator.

Reviewed by:	swildner@dragonflybsd.org
Approved by:	cperciva
Obtained from:	DragonFlyBSD
MFC after:	1 week
This commit is contained in:
Eitan Adler 2012-11-20 01:57:21 +00:00
parent f77a2d2f24
commit 18ba28c82c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=243320
2 changed files with 35 additions and 10 deletions

View File

@ -31,7 +31,7 @@
.\" @(#)cut.1 8.1 (Berkeley) 6/6/93 .\" @(#)cut.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd December 21, 2006 .Dd August 8, 2012
.Dt CUT 1 .Dt CUT 1
.Os .Os
.Sh NAME .Sh NAME
@ -47,7 +47,7 @@
.Op Ar .Op Ar
.Nm .Nm
.Fl f Ar list .Fl f Ar list
.Op Fl d Ar delim .Op Fl w | Fl d Ar delim
.Op Fl s .Op Fl s
.Op Ar .Op Ar
.Sh DESCRIPTION .Sh DESCRIPTION
@ -119,6 +119,9 @@ that form the character are selected.
.It Fl s .It Fl s
Suppress lines with no field delimiter characters. Suppress lines with no field delimiter characters.
Unless specified, lines with no delimiters are passed through unmodified. Unless specified, lines with no delimiters are passed through unmodified.
.It Fl w
Use whitespace (spaces and tabs) as the delimiter.
Consecutive spaces and tabs count as one single field separator.
.El .El
.Sh ENVIRONMENT .Sh ENVIRONMENT
The The

View File

@ -58,6 +58,7 @@ static int dflag;
static int fflag; static int fflag;
static int nflag; static int nflag;
static int sflag; static int sflag;
static int wflag;
static size_t autostart, autostop, maxval; static size_t autostart, autostop, maxval;
static char * positions; static char * positions;
@ -67,6 +68,7 @@ static int b_n_cut(FILE *, const char *);
static int c_cut(FILE *, const char *); static int c_cut(FILE *, const char *);
static int f_cut(FILE *, const char *); static int f_cut(FILE *, const char *);
static void get_list(char *); static void get_list(char *);
static int is_delim(int);
static void needpos(size_t); static void needpos(size_t);
static void usage(void); static void usage(void);
@ -84,7 +86,7 @@ main(int argc, char *argv[])
dchar = '\t'; /* default delimiter is \t */ dchar = '\t'; /* default delimiter is \t */
strcpy(dcharmb, "\t"); strcpy(dcharmb, "\t");
while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1) while ((ch = getopt(argc, argv, "b:c:d:f:snw")) != -1)
switch(ch) { switch(ch) {
case 'b': case 'b':
get_list(optarg); get_list(optarg);
@ -111,6 +113,9 @@ main(int argc, char *argv[])
case 'n': case 'n':
nflag = 1; nflag = 1;
break; break;
case 'w':
wflag = 1;
break;
case '?': case '?':
default: default:
usage(); usage();
@ -119,9 +124,9 @@ main(int argc, char *argv[])
argv += optind; argv += optind;
if (fflag) { if (fflag) {
if (bflag || cflag || nflag) if (bflag || cflag || nflag || (wflag && dflag))
usage(); usage();
} else if (!(bflag || cflag) || dflag || sflag) } else if (!(bflag || cflag) || dflag || sflag || wflag)
usage(); usage();
else if (!bflag && nflag) else if (!bflag && nflag)
usage(); usage();
@ -358,19 +363,31 @@ c_cut(FILE *fp, const char *fname)
return (0); return (0);
} }
static int
is_delim(int ch)
{
if (wflag) {
if (ch == ' ' || ch == '\t')
return 1;
} else {
if (ch == dchar)
return 1;
}
return 0;
}
static int static int
f_cut(FILE *fp, const char *fname) f_cut(FILE *fp, const char *fname)
{ {
wchar_t ch; wchar_t ch;
int field, i, isdelim; int field, i, isdelim;
char *pos, *p; char *pos, *p;
wchar_t sep;
int output; int output;
char *lbuf, *mlbuf; char *lbuf, *mlbuf;
size_t clen, lbuflen, reallen; size_t clen, lbuflen, reallen;
mlbuf = NULL; mlbuf = NULL;
for (sep = dchar; (lbuf = fgetln(fp, &lbuflen)) != NULL;) { while ((lbuf = fgetln(fp, &lbuflen)) != NULL) {
reallen = lbuflen; reallen = lbuflen;
/* Assert EOL has a newline. */ /* Assert EOL has a newline. */
if (*(lbuf + lbuflen - 1) != '\n') { if (*(lbuf + lbuflen - 1) != '\n') {
@ -394,7 +411,7 @@ f_cut(FILE *fp, const char *fname)
if (clen == 0) if (clen == 0)
clen = 1; clen = 1;
/* this should work if newline is delimiter */ /* this should work if newline is delimiter */
if (ch == sep) if (is_delim(ch))
isdelim = 1; isdelim = 1;
if (ch == '\n') { if (ch == '\n') {
if (!isdelim && !sflag) if (!isdelim && !sflag)
@ -421,8 +438,13 @@ f_cut(FILE *fp, const char *fname)
if (clen == 0) if (clen == 0)
clen = 1; clen = 1;
p += clen; p += clen;
if (ch == '\n' || ch == sep) if (ch == '\n' || is_delim(ch)) {
/* compress whitespace */
if (wflag && ch != '\n')
while (is_delim(*p))
p++;
break; break;
}
if (*pos) if (*pos)
for (i = 0; i < (int)clen; i++) for (i = 0; i < (int)clen; i++)
putchar(p[i - clen]); putchar(p[i - clen]);
@ -452,6 +474,6 @@ usage(void)
(void)fprintf(stderr, "%s\n%s\n%s\n", (void)fprintf(stderr, "%s\n%s\n%s\n",
"usage: cut -b list [-n] [file ...]", "usage: cut -b list [-n] [file ...]",
" cut -c list [file ...]", " cut -c list [file ...]",
" cut -f list [-s] [-d delim] [file ...]"); " cut -f list [-s] [-w | -d delim] [file ...]");
exit(1); exit(1);
} }