last day (14 days later) » 

12:08 PM
5
A: Only cat from specific line X (with a pattern) to other specific line Y (with a pattern)

mikeservsed -n '/foo/,/goo/p;/goo/q' <bigfile That would print only those lines. If you wanted the line numbers you'd add an =. sed -n '/foo/=;/goo/=;//q' <bigfile The q is important because it quits the input when it is called - else sed will continue to read the infile through to the end. If you ...

 
@HalosGhost - I edited it. Thanks for the inspiration - your own answer gets my vote.
@HalosGhost - thanks again.
 
sed -n '/foo/,/goo/!d;//!p;/goo/q' won't work with all sed implementations (//!p will only match on goo with some).
 
@StéphaneChazelas - which are those if you don't mind? That confuses me - specifically the note here about c[2addr]c‌​‌​\ text Delete the pattern space. With a 0 or 1 address or at the end of a 2-address range, place text on the output and start the next cycle. Maybe I should make that a question, huh? It's just that - GNU sed at, least - seems to do all of them. Or else, when used like I do above, only the specifically addressed lines. Is it a bug, do you think?
 
In the original one (tested on Unix V7) and probably all the derived commercial Unices (tested Solaris as well) as well as FreeBSD (and probably all the BSDs). ls / | sed -n '/dev/,/lib/!d;//!p;/lib/q' shows dev. Only exception I've found so far is GNU sed.
 
@StéphaneChazelas - I think it's a GNU bug, maybe. I've been up and down their sed info pages and I've never noticed any reference to that behavior. Not doing so does seem a little out-of-character considering the explicit coverage of N and its last line behavior in the BUGS section. I suppose I should report it. Anyway, I updated the answer to reflect it.
 
12:08 PM
Both make sense. // matches on the last pattern. For GNU sed, it'll be the last pattern match run, while on other seds, that'll be the last one lexically on the sed command script (even though it was not run. /goo/ is not run in /foo/,/goo/ if /foo/ matched). I would even say that the GNU sed behaviour is more inline with the POSIX spec.
 
@StéphaneChazelas - so your point is that it is a bug in the spec for it not being specific enough? But what of the /ran/,/ge/c\\ behavior? They seem related... And besides, in my example - if it really were doing the range again - then shouldn't it !p the whole range? I didn't even see your answer till just now...
 
I'd say yes, the spec is not specific enough. I don't see what's the problem with c though. That seems unambiguous to me and I don't see how that's related to //. The ambiguity is about what // matches on when the previous match is part of a /x/,/y/ address range. There's also ambiguity in ls / | sed '/s/s/i/u/;s//<&>/g' for instance.
 
When I talk about c I mean... I just realized I mean nonsense. The spec says delete the pattern space, at the end of the range place text on output. For some reason I guess I interpreted it to mean that c should behave specially and only affect the last line in a range - but of course it must first delete the pattern space for every line in the range but the last.
I still don't understand why /ran/,/ge/!d;//!p shouldn't first not delete all lines in the range, next not print same.
And I'm trying to decipher your last now..
Oh - which address follows? I don't see the ambiguity there. It should always be the last address specified - regardless of a match. In your ls / | statement - the way I understand it, anyway, - s//<&>/g should always print as many <i>s as it might.
If an RE is empty (that is, no pattern is specified) sed shall behave as if the last RE used in the last command applied (either as an address or as part of a substitute command) was specified.
The GNU sed info manual goes so far as to point out that empty addresses are filled before even the regex is compiled.
 
1:07 PM
You have to bear in mind that sed processes the sed script for each line in turn. In sed '/a/,/b/!d; //!p', for a given line, if the range has not been entered yet, it will try to match /a/ and if not /b/. If we're not within the range then d is run, then we start a new cycle with the next line. If we are, at the point we reach //!p we've either entered the range by matching /a/ (in which case /b/ has not been checked) or we've not left the range by failing to match /b/.
(in which case /a/ has not been checked)
So it makes sense for GNU sed's // to repeat that last /a/ or /b/ instead of always /b/ as other implementations do. Because that's the last pattern that sed used (at runtime).
 
^^^thank you***
I've used that for awhile, but I never really got how it worked.
 
In sed '/s/!s/i/u/; s//<&>/g' which is a better example than my initial`/s/s/i/u/; s//<&>/g`, One may argue that you should see some <s> and <i> for lines not containing s (like GNU sed, but not other seds do)
 
I've thought that - like if the /s/ doesn't match then the s/i/ doesn't happen right?
That bugged me too, until I read that bit in the info manual.
Obviously it's not the spec, but it made sense.
And I think that is the way it should always work. It's confusing enough without adding side-effects.
Wouldn't you say?
You get <s> out of that?
Great.
That just added side effects...
this is info sed. I probably read it wrong. 8 times:
The empty regular expression // repeats the last regular expression match (the same holds if the empty regular expression is passed to the s command). Note that modifiers to regular expressions are evaluated when the regular expression is compiled, thus it is invalid to specify them together with the empty regular expression.
I think they cop-out there.
 

last day (14 days later) »