A little extended problem from "cat line x to line y on a huge file":
I have a huge file (2-3 GB). I'd like to cat/print only from the line having "foo:" to the line having "goo:". Assume that "foo:" and "goo:" only appear once in a file; "foo:" proceeds "goo:".
So far this is my approach:
- First, find the line with "foo:" and "goo:":
grep -nr "foo:" bigfile
- Returns
123456: foo: hello world!
and654321: goo: good bye!
- Once I know these starting and ending line numbers, and the difference (654321-123456=530865) I can do selective cat:
tail -n+123456 bigfile | head -n 530865
My question is that how can I effectively substitute the line number constants with expressions (e.g., grep ...)?
I can write a simple Python script but want to achieve it using only combining commands.
sed
command oversed -n '/foo:/!{ /goo:/,/foo:/!p; }' bigFile
? (Not being argumentative; generally curious.) – HalosGhost Sep 02 '14 at 03:04sed
solution in my post considering that what I posted was not actually equivalent (in execution flow) to myawk
solution. I'll leave my post toawk
:) – HalosGhost Sep 02 '14 at 03:30sed -n '/foo/,/goo/!d;//!p;/goo/q'
won't work with allsed
implementations (//!p
will only match ongoo
with some). – Stéphane Chazelas Sep 02 '14 at 06:24c
[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 - GNUsed
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? – mikeserv Sep 02 '14 at 06:57ls / | sed -n '/dev/,/lib/!d;//!p;/lib/q'
showsdev
. Only exception I've found so far is GNU sed. – Stéphane Chazelas Sep 02 '14 at 08:39sed
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 ofN
and its last line behavior in the BUGS section. I suppose I should report it. Anyway, I updated the answer to reflect it. – mikeserv Sep 02 '14 at 09:19//
matches on the last pattern. For GNUsed
, it'll be the last pattern match run, while on othersed
s, 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éphane Chazelas Sep 02 '14 at 09:23/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... – mikeserv Sep 02 '14 at 09:26c
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 inls / | sed '/s/s/i/u/;s//<&>/g'
for instance. – Stéphane Chazelas Sep 02 '14 at 10:23