[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