sed(1) Add support for "-" file

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

sed(1) Add support for "-" file

Martijn van Duren-5
According to POSIX[0]:
The standard input shall be used if no file operands are specified, and
shall be used if a file operand is '-' and the implementation treats the
'-' as meaning standard input. Otherwise, the standard input shall not  
be used. See the INPUT FILES section.

Which we currently don't support:
$ cat /tmp/test
test
$ printf "foo\ntest\nbaz\n" | sed "s/test/bar/" - /tmp/test
sed: 0: -: No such file or directory
bar

So let's fix that while reducing the LoC.
I choose too accept stdin with the -i flag, because:
1) It allows us to combine it as an inplace editor and filter in a
   single operation.
2) It further simplifies the code.

So now we can do fancy stuff like:
$ printf "foo\ntest\nbaz\n" | ./sed "s/test/bar/" /tmp/test -
bar
foo
bar
baz

and
$ printf "foo\ntest\nbaz\n" | ./sed -i "s/test/bar/" /tmp/test -
foo
bar
baz
$ cat /tmp/test
bar

Note that gsed does support the "-" filename, but treats - in
combination with -i as a filename, instead of stdin:
$ echo test > -
$ gsed -i s/test/bar/ -
$ cat ./-
bar

OK?

martijn@

Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.38
diff -u -p -r1.38 main.c
--- main.c 14 Nov 2018 10:59:33 -0000 1.38
+++ main.c 6 Dec 2018 07:28:15 -0000
@@ -345,32 +345,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
  size_t len;
  char *p;
  int c, fd;
- static int firstfile;
-
- if (infile == NULL) {
- /* stdin? */
- if (files->fname == NULL) {
- if (inplace != NULL)
- error(FATAL, "-i may not be used with stdin");
- infile = stdin;
- fname = "stdin";
- outfile = stdout;
- outfname = "stdout";
- }
-
- firstfile = 1;
- }
+ static int firstfile = 1;
 
  for (;;) {
  if (infile != NULL && (c = getc(infile)) != EOF) {
  (void)ungetc(c, infile);
  break;
  }
- /* If we are here then either eof or no files are open yet */
- if (infile == stdin) {
- sp->len = 0;
- return (0);
- }
  finish_file();
  if (firstfile == 0)
  files = files->next;
@@ -381,6 +362,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
  return (0);
  }
  fname = files->fname;
+ if (fname == NULL || strcmp(fname, "-") == 0) {
+ infile = stdin;
+ fname = "stdin";
+ outfile = stdout;
+ outfname = "stdout";
+ break;
+ }
  if (inplace != NULL) {
  if (lstat(fname, &sb) != 0)
  error(FATAL, "%s: %s", fname,

Reply | Threaded
Open this post in threaded view
|

Re: sed(1) Add support for "-" file

Todd C. Miller-2
This has the side effect of closing stdin on EOF but I don't think
that is a problem.  OK millert@

 - todd