sed-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Command to terminate current stream processing


From: Assaf Gordon
Subject: Re: Command to terminate current stream processing
Date: Tue, 9 Apr 2019 09:14:02 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1

Hello,

On 2019-04-09 1:00 a.m., Konstantin Andreev wrote:
sed has convenient commands "q" and "Q" that allow to break stream processing, if you are not interested in the stream any more. E.g., looking for C header inclusion guard may be
[...]
If I understand correctly, the option "-s" has evolved as a side effect of "-i" option, and, as such, is assumed to work as shortcut that turns iterators like

| $ for j in A B C; do sed SCRIPT $j; done

into the

| $ sed -s SCRIPT A B C

I do not know if "-s/--separate" evolved as a side-effect of "-i" - it
works independently of "-i" (as in your examples above)...
It was added sometime between sed 3.02 and sed 3.95 (circa 1999-2002),
I do no have exact details about it (other are welcomed to comment).

However, "-s" does not work this way if SCRIPT encounters q/Q command: sed just quits without processing further streams. Formally correct and agreed with documentation, this breaks "-s" option idea.

It is important to realize (and perhaps we should document it better),
that "-s" only affects address matching. It does not affect commands at
all.

I think it was mainly added so that "$" (end of stream / last line)
address condition could match each file instead of just once.

For example:

   $ seq 10 19 > a ; seq 200 209 > b; seq 3000 3009 > c ;

   $ sed -n '1p;$p' a b c
   10
   3009

   $ sed -s -n '1p;$p' a b c
   10
   19
   200
   209
   3000
   3009

I believe this is because in past times, when sed was able to process only one stream at one run, "terminate stream" and "terminate sed" were the same, and documentation for "q/Q" didn't care about the difference.

Anyway, the action of "q/Q" in multi-stream environment is now beyond changing.

But, ... may we introduce a new command, that behaves identically to "q" in a single-stream environment, but just breaks current stream processing in a multi-stream environment?

"q/Q" is quit (=terminate sed's process) regardless of "-s".

It seems you are looking for a functionality similar to awk's "nextfile" command.

While sed has no such built-in command, it is easy to achieve this
using the following sequence, which consumes and discards all input
until the last line (and because of "-s/--separate", the
last line detection is per-file):

  :consume
  $d
  N
  z
  b consume

(a similar sequence is documented in the 'Q' command, here:
https://www.gnu.org/software/sed/manual/sed.html#Extended-Commands ).


For example, if you wanted to 'nextfile' when a line contains
the character '4', you could run:

  $ sed -s '/4/{:x;$d;N;z;bx}' a b c
  10
  11
  12
  13
  200
  201
  202
  203
  3000
  3001
  3002
  3003

If you wanted to also print the matching line, just add 'p':

  $ sed -s '/4/{p;:x;$d;N;z;bx}' a b c
  10
  11
  12
  13
  14
  200
  201
  202
  203
  204
  3000
  3001
  3002
  3003
  3004


Hope this helps,
 - assaf





reply via email to

[Prev in Thread] Current Thread [Next in Thread]