| Newsgroups |
gmane.editors.sed.user |
| Message-ID |
<[email protected]> |
On 2015-03-05 14:21, 'Seeger, Stephan'
> I'm really new to using sed. While experimenting in order to print
> ranges without its BEGIN and END patterns I accidentially came
> across that given a string variable:
New to sed and you stumble upon this awesome hack?! Nicely done! I
don't think I've ever seen this one before
> sed -n '/second/,/fourth/{//!p}'
[snip]
> Unfortunately I didn't find this described anywhere in manuals nor
> the internet. Probably there's anyone out there who can explain
> whether this is a bug or a feature...and how/why it works.
As best I can tell, this is working as a side-effect of documented
behavior. The general process/flow would be something like
1) check if this line matches the start-of-range pattern
("second"). As a side-effect of this, the "last pattern" gets set to
the same thing and we internally annotate that we're inside this
range.
2) it matches, so do the stuff inside the "{...}"
3) Check to see if the current line matches the "last
pattern" ("//"). It does, so we don't ("!") execute the print command
4) proceed to the next line
5) we're inside the range, so we check for the end-of-range pattern.
As a side-effect, the "last pattern" gets set. It doesn't match, so
we continue to execute the "{...}"
6) we check if "third" matches the "last pattern" (now the
end-of-range pattern). It doesn't, so we print it
7) we're inside the range, so we check for the end of the range.
As a side-effect, the "last pattern" gets set. It does match, so
we continue to execute the "{...}", and then unset the internal
"within this range" flag
8) executing the "{...}", we check if "fourth" matches the "last
pattern". It does, so we don't print it.
9) we're now outside the range, so we resume looking for "second"
and
It doesn't even break if the start-pattern appears within the range:
$ printf '%s\n' a b c d e d f g h i j | sed -n '/d/,/g/{//!p}'
e
d
f
(note that "d" does come between the opening "d" and the closing "g",
so it gets printed)
So I'd claim that this is some of the most elegant sed hackery I've
seen in a while (at least for such a short piece of code).
-tim