printing range of lines in sed

printing range of lines in sed

Post by Mark Harriso » Wed, 18 Jun 2003 03:22:44



I know that 'sed 5q' will print the first 5 lines of a file.
How can I do the equivalent of

        awk 'NR>=3&&NR<=5'

to get lines 3-5 of a file?

Many TIA!
Mark

--
Mark Harrison
Pixar Animation Studios

 
 
 

printing range of lines in sed

Post by Juha Laih » Wed, 18 Jun 2003 04:02:01



Quote:>I know that 'sed 5q' will print the first 5 lines of a file.
>How can I do the equivalent of

>    awk 'NR>=3&&NR<=5'

>to get lines 3-5 of a file?

sed -n '3,5 p'

-n : disable output (so, don't print every line that is processed)
3,5: range of lines
p  : print (command performed on lines matching the range condition)
--
Wolf  a.k.a.  Juha Laiho     Espoo, Finland

         PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
"...cancel my subscription to the resurrection!" (Jim Morrison)

 
 
 

printing range of lines in sed

Post by Stephane CHAZELA » Wed, 18 Jun 2003 09:25:18



> I know that 'sed 5q' will print the first 5 lines of a file.
> How can I do the equivalent of

>    awk 'NR>=3&&NR<=5'

> to get lines 3-5 of a file?

awk 'NR>=3; NR==5{exit}'

sed '5q;3,$!d'

--
Stphane

 
 
 

printing range of lines in sed

Post by Valentin Nechaye » Wed, 18 Jun 2003 15:59:34


MH> I know that 'sed 5q' will print the first 5 lines of a file.
MH> How can I do the equivalent of
MH>  awk 'NR>=3&&NR<=5'
MH> to get lines 3-5 of a file?

Answering to another question: head/tail is more lightweight than sed:
head -5 | tail -3

-netch-

 
 
 

printing range of lines in sed

Post by Frank Cusac » Wed, 18 Jun 2003 17:17:57




> MH> I know that 'sed 5q' will print the first 5 lines of a file.
> MH> How can I do the equivalent of
> MH>     awk 'NR>=3&&NR<=5'
> MH> to get lines 3-5 of a file?

> Answering to another question: head/tail is more lightweight than sed:
> head -5 | tail -3

Not really.

Try a 10,000 line file where you want lines 3000-3003.

sed -n '3000,3003p;3003q' reads in only 3003 lines.
'head -3003 | tail -3' reads in 3003 lines, sends them over a pipe to tail,
which again reads in the 3003 lines.

Same thing for lines 3-5, you just don't notice it on that scale.

/fc

 
 
 

printing range of lines in sed

Post by Valentin Nechaye » Wed, 18 Jun 2003 22:51:41



> MH>> How can I do the equivalent of
> MH>>         awk 'NR>=3&&NR<=5'
> MH>> to get lines 3-5 of a file?
>> Answering to another question: head/tail is more lightweight than sed:
>> head -5 | tail -3

FC> Not really.
FC> Try a 10,000 line file where you want lines 3000-3003.

I said only for case of lines 3...5.

FC> sed -n '3000,3003p;3003q' reads in only 3003 lines.
FC> 'head -3003 | tail -3' reads in 3003 lines, sends them over a pipe to tail,
FC> which again reads in the 3003 lines.

Of course.

-netch-

 
 
 

printing range of lines in sed

Post by Frank Cusac » Thu, 19 Jun 2003 14:21:09




>> MH>> How can I do the equivalent of
>> MH>>     awk 'NR>=3&&NR<=5'
>> MH>> to get lines 3-5 of a file?
>>> Answering to another question: head/tail is more lightweight than sed:
>>> head -5 | tail -3
> FC> Not really.
> FC> Try a 10,000 line file where you want lines 3000-3003.

> I said only for case of lines 3...5.

Even then, you are reading the data then passing it over a pipe, so you
still incur an extra copy.  Granted, it's just 5 lines of data.

Even for 3 lines, I don't see how setting up a pipe and forking a separate
process is lighter weight than a sed command that doesn't use regexes.

3,5p is trivial to parse and execute.

/fc

 
 
 

printing range of lines in sed

Post by Andy Isaacs » Fri, 20 Jun 2003 04:20:42





>> MH>> How can I do the equivalent of
>> MH>>     awk 'NR>=3&&NR<=5'
>> MH>> to get lines 3-5 of a file?
>>> Answering to another question: head/tail is more lightweight than sed:
>>> head -5 | tail -3
>FC> Not really.
>FC> Try a 10,000 line file where you want lines 3000-3003.

>I said only for case of lines 3...5.

>FC> sed -n '3000,3003p;3003q' reads in only 3003 lines.
>FC> 'head -3003 | tail -3' reads in 3003 lines, sends them over a pipe to tail,
>FC> which again reads in the 3003 lines.

>Of course.

Even for just 3 lines, forking an additional process is a big expense.
I wrote some simple code to run the test repeatedly (not using shell
loops to avoid shell overhead), and found that the sed command is
significantly faster than running two processes.

Running on my OpenBSD laptop, 100 sed processes took 0.698 seconds
while 100 head|tail pipes took 1.12 seconds.

Of course it's very important to put the '3003q' in there, because
otherwise sed ends up processing the entire file.  Not too bad if
you're processing /etc/motd but bad if you're processing
/usr/share/dict/words.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
    int i, n;

    if(argc != 3) exit(1);

    n = atoi(argv[1]);

    for(i=0; i<n; i++) {
        switch(fork()) {
            case -1:
                fprintf(stderr, "fork: %s\n", strerror(errno));
                exit(1);
            case 0:
                if(execl("/bin/sh", "sh", "-c", argv[2]) == -1) {
                    fprintf(stderr, "execl: %s\n", strerror(errno));
                    exit(1);
                }
            default:
                if(wait(0) == -1) {
                    fprintf(stderr, "wait: %s\n", strerror(errno));
                    exit(1);
                }
                break;
        }
    }
    return 0;

Quote:}

./a.out 100 '< /tmp/a sed -n "3,5p;5q"' > /dev/null
0.25s user 0.41s system 94% cpu 0.698 total
./a.out 100 '< /tmp/a head -5|tail -3' > /dev/null
0.30s user 0.75s system 94% cpu 1.112 total

-andy

 
 
 

1. how can I join a range of lines in sed?

I have a file with sections inside BEGIN/END pairs.  (In 99% of the
interesting cases, there are only either one or two lines between the
two dot lines, if that makes any difference.)  I want to "join" (in the
sense of the ed/ex/vi command) the lines together, and delete the
sentinal lines.  I could do this easily enough in awk, but the rest of
the job is done in a sed script, and I'd like to keep all the work
together if I can.

Somehow, I need to use the sed N command to "append the next line of
input to the pattern space with an embedded newline."  Without the N,
the pattern space consists of only one line at a time.  I've tried
substitutions and the t command (yuchh, I haven't used an if/goto
statement in over a decade!), but it never quite worked; e.g, this:

/^BEGIN/,/^END/{
        :loop
        N
        s/\nEND$//
        t done
        b loop
        :done
        s/^BEGIN\n//
        s/\n/ /g
        s/.*/.FOO "&"/
        p
        d

(the "p" and "d" are an attempt to flush the pattern space) run on the
following input:

Now
is
the
time
BEGIN
for
all
good
men
END
to
come
to
the
aid
BEGIN
of
their
country.
END

produced this:

Now
is
the
time
.FOO "for all good men"
.FOO "to come"
.FOO "to the"
.FOO "aid BEGIN"
.FOO "of their"
.FOO "country."

instead of this:

Now
is
the
time
.FOO "for all good men"
to
come
to
the
aid
.FOO "of their country."

Well, it worked through the first pair, but it doesn't seem to stop
right.

Any thoughts?  (I'll post a summary of e-mail responses, eventually,
but I'm notoriously slow.  I *will* read postings to this group.
Posting *and* mailing an answer would be greatly appreciated!)

Paul S. R. Chisholm, AT&T Bell Laboratories

I'm not speaking for the company, I'm just speaking my mind.

2. Tivloi backups -Reporting mechanism

3. Print 2nd line after target line in sed

4. TIFF-to-Jpeg batch converter? (fwd)

5. what sed command to print the first line and the last line

6. evolution questions

7. Print 2nd line after target line in sed

8. 2.5.38 s390 fixes: 05_dasd.

9. How can I join a range of lines in SED ?

10. Print 2nd line after target line in sed

11. Q:print nth line of file using SED

12. print previous and target line w/ sed

13. how do I tell SED to print only matching lines?