sed -ne 'x' -e '/PREV/ {x; /CURR/ p; x}'
> echo -e "PREV\nCURR\nCURR\nCURR\nPREV\nRED" | sed -ne 'x' -e '/PREV/ {x; /CURR/ p; x}'
CURR
This uses sed's hold buffer. I'll break it down: sed -n
The `-n` tells sed no to print anything out. By default, sed prints out whatever is left when processing. We'll tell it with the `p` command when to do so. sed -ne 'x'
`-e` indicates we are specifying one of the scripts sed will execute. The command `x` switches the current line with whatever is in the hold buffer. We'll do this on every line. sed -ne 'x' -e '/PREV/
The next command will only run on lines that contain `PREV`. But, because we've been putting lines in the hold buffer, we'll only execute on lines after `PREV` when it has been switched out of the hold buffer. sed -ne 'x' -e '/PREV/ { ... }'
The braces indicate all commands should be run when we see this match. sed -ne 'x' -e '/PREV/ { x; ... }'
First, we switch the hold buffer with the line buffer. sed -ne 'x' -e '/PREV/ { x; /CURR/ p; ... }'
Then, we only print out the line if it contains CURR. sed -ne 'x' -e '/PREV/ {x; /CURR/ p; x}'
Finally, we switch them back in case there is overlap in our matches. (Give `echo -e "PREV\nPREVCURR\nCURR\nCURR\nPREV\nRED"` a try with this.)All that said, I'm pretty sure the `awk` script is much simpler and more direct, but I wanted to share how one might accomplish this was sed.
The time I spent learning this probably would've been better spend on awk, but this tutorial[0], was so good and so easy, it taught me nearly everything I know about sed.
Plan9's awk(1)[0] man page provides a precise and concise (a few paragraphs) presentation of the core features of all awk implementations.
Tutorials bring practical knowledge, but often lack complete and self-contained descriptions of those nifty little tools.
It's short and to the point, has good examples, and cuts most of the usual fluff like "what is a variable?". Its base assumptions are: You know how to program, and you're here to learn AWK. Let's get to it.
I dearly wish there'd be more books like it for other languages.
It's always delightful to see competent authors demonstrate how much sophistication is achievable in about 100 lines of simple code, by comparison with the "the Dog class inherits from the Animal class" type of examples, or "real-life" codebases. This book is definitely in the former category.
> I dearly wish there'd be more books like it for other languages.
This all reminds me of a well-known regular expression matcher[0], in about 30 lines of C, featured in "The Practice of Programming"[1].
More generally, even without dedicated books, there are common simple-but-sophisticated type of programs that are great to get to know a language, once you have basic programming skills: standard UNIX tools (cat(1), grep(1), etc.), λ-calculus interpreter, LISP interpreter, raytracer, etc. One can often find online versions serving as "solutions."
[0]: https://www.cs.princeton.edu/courses/archive/spr09/cos333/be...
[1]: https://en.wikipedia.org/wiki/The_Practice_of_Programming
Saddens me to see people selling crappy "e-books" or whatetver on text processing on HN. Compared to the older generations that used UNIX, the level of knowledge is lacking. IMHO.
This book from Tim Oreilly is an old favourite and has one of the nuttiest explanations of the hold space. See page 375.
https://www.oreilly.com/openbook/utp/UnixTextProcessing.pdf
https://web.archive.org/web/20230514225639if_/https://www.or...
As a NetBSD user, I found this books useful; all the utilities explained in it are still in the NetBSD userland.