On 2021-01-25, Sebastian Benoit wrote: > Sebastian Benoit(be...@openbsd.org) on 2021.01.25 00:27:05 +0100: > > Theo de Raadt(dera...@openbsd.org) on 2021.01.24 16:01:32 -0700: > > > Stuart Henderson <s...@spacehopper.org> wrote: > > > > > > > On 2021/01/24 12:10, Theo de Raadt wrote: > > > > > I completely despise that the option is called "--null". > > > > > > > > > > Someone was a complete idiot. > > > > > > > > gnu grep has both --null and -z for this (why do they do that?!). > > > > If it's added as --null it should be added as -z too. > > > > > > > > Looking at Debian codesearch most things using it as --null use other > > > > long options that we don't have. Maybe just adding as -z would be > > > > enough. It does seem a useful and fairly widely supported feature. > > > > > > Yes, maybe just add -z. > > > > Actually it's "-Z, --null". The lowercase -z in gnu grep is > > > > -z, --null-data > > Treat input and output data as sequences of lines, each > > terminated by a zero byte (the ASCII NUL character) instead of > > a newline. Like the -Z or --null option, this option can be > > used with commands like sort-z to process arbitrary file > > names. > > And we already have -z for "force grep to behave as zgrep". > > Diff below with tedu@ suggestion and changed manpage text.
What happened to -Z? > > > > > Note that we have the -z in sort(1), which at least is consistent. > > That also is a non-posix extension. > > > > > > Should have been -0 to match xargs and be similar to find's -print0 > > > > but it's too late for that now. > > > > > > Yes it should have been -0. > > > > > > But unfortunately some an uneducated idiot got involved. None of this > > > is standardized. Unix script portability is being ruined by idiots, not > > > just the people proposing it or writing it originally, but also the people > > > who don't say "wrong" quickly enough. And much of this is because of > > > intentional development silos. > > diff --git usr.bin/grep/grep.1 usr.bin/grep/grep.1 > index 5cc228df222..e1edae7e432 100644 > --- usr.bin/grep/grep.1 > +++ usr.bin/grep/grep.1 > @@ -49,6 +49,7 @@ > .Op Fl -context Ns Op = Ns Ar num > .Op Fl -label Ns = Ns Ar name > .Op Fl -line-buffered > +.Op Fl -null > .Op Ar pattern > .Op Ar > .Ek > @@ -297,6 +298,16 @@ instead of the filename before lines. > Force output to be line buffered. > By default, output is line buffered when standard output is a terminal > and block buffered otherwise. > +.It Fl -null > +Output a zero byte instead of the character that normally follows a > +file name. > +This option makes the output unambiguous, even in the presence of file > +names containing unusual characters like newlines, making the output > +suitable for use with the > +.Fl 0 > +option to > +.Xr xargs 1 . > +This option is a non-POSIX extension and may not be portable. > .El > .Sh EXIT STATUS > The > diff --git usr.bin/grep/grep.c usr.bin/grep/grep.c > index f41b5e20ca6..279d949fae7 100644 > --- usr.bin/grep/grep.c > +++ usr.bin/grep/grep.c > @@ -80,6 +80,7 @@ int vflag; /* -v: only show non-matching lines */ > int wflag; /* -w: pattern must start and end on word boundaries */ > int xflag; /* -x: pattern must match entire line */ > int lbflag; /* --line-buffered */ > +int nullflag; /* --null */ > const char *labelname; /* --label=name */ > > int binbehave = BIN_FILE_BIN; > @@ -89,6 +90,7 @@ enum { > HELP_OPT, > MMAP_OPT, > LINEBUF_OPT, > + NULL_OPT, > LABEL_OPT, > }; > > @@ -134,6 +136,7 @@ static const struct option long_options[] = > {"mmap", no_argument, NULL, MMAP_OPT}, > {"label", required_argument, NULL, LABEL_OPT}, > {"line-buffered", no_argument, NULL, LINEBUF_OPT}, > + {"null", no_argument, NULL, NULL_OPT}, > {"after-context", required_argument, NULL, 'A'}, > {"before-context", required_argument, NULL, 'B'}, > {"context", optional_argument, NULL, 'C'}, > @@ -436,6 +439,9 @@ main(int argc, char *argv[]) > case LINEBUF_OPT: > lbflag = 1; > break; > + case NULL_OPT: > + nullflag = 1; > + break; > case HELP_OPT: > default: > usage(); > diff --git usr.bin/grep/grep.h usr.bin/grep/grep.h > index b3d24ae662b..37e295d4d40 100644 > --- usr.bin/grep/grep.h > +++ usr.bin/grep/grep.h > @@ -68,7 +68,7 @@ extern int cflags, eflags; > extern int Aflag, Bflag, Eflag, Fflag, Hflag, Lflag, > Rflag, Zflag, > bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag, qflag, > - sflag, vflag, wflag, xflag; > + sflag, vflag, wflag, xflag, nullflag; > extern int binbehave; > extern const char *labelname; > > diff --git usr.bin/grep/util.c usr.bin/grep/util.c > index e16d08e7d85..546bd09dc3b 100644 > --- usr.bin/grep/util.c > +++ usr.bin/grep/util.c > @@ -172,13 +172,13 @@ procfile(char *fn) > > if (cflag) { > if (!hflag) > - printf("%s:", ln.file); > + printf("%s%c", ln.file, nullflag ? '\0' : ':'); > printf("%llu%s\n", c, overflow ? "+" : ""); > } > if (lflag && c != 0) > - printf("%s\n", fn); > + printf("%s%c", fn, nullflag ? '\0' : '\n'); > if (Lflag && c == 0) > - printf("%s\n", fn); > + printf("%s%c", fn, nullflag ? '\0' : '\n'); > if (c && !cflag && !lflag && !Lflag && > binbehave == BIN_FILE_BIN && nottext && !qflag) > printf("Binary file %s matches\n", fn); > @@ -660,7 +660,7 @@ printline(str_t *line, int sep, regmatch_t *pmatch) > } > if (nflag) { > if (n) > - putchar(sep); > + putchar(nullflag ? '\0' : sep); > printf("%lld", line->line_no); > ++n; > } > >