Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

head -100 foo | tail -20

4 views
Skip to first unread message

J Krugman

unread,
Apr 13, 2005, 12:46:13 PM4/13/05
to

Is there a standard Unix utility that will print a specified range
of lines? If I wanted to print, say, lines 81 through 100 of file
foo, I'd use

% head -100 foo | tail -20

but I'm looking for some command, say bar, that would yield the
same results without requiring a pipe, e.g.

% bar 81,100 foo

or something like this. (Actually, such a command would be a
generalization of both head and tail.)

Thanks!

jill

--
To s&e^n]d me m~a}i]l r%e*m?o\v[e bit from my a|d)d:r{e:s]s.

Ceri Davies

unread,
Apr 13, 2005, 12:58:07 PM4/13/05
to
On 2005-04-13, J Krugman <jkrug...@yahbitoo.com> wrote:
>
>
> Is there a standard Unix utility that will print a specified range
> of lines? If I wanted to print, say, lines 81 through 100 of file
> foo, I'd use
>
> % head -100 foo | tail -20
>
> but I'm looking for some command, say bar, that would yield the
> same results without requiring a pipe, e.g.
>
> % bar 81,100 foo

sed -n 81,100p < foo

Ceri
--
Only two things are infinite, the universe and human stupidity, and I'm
not sure about the former. -- Einstein (attrib.)

Chris F.A. Johnson

unread,
Apr 13, 2005, 1:01:09 PM4/13/05
to
On Wed, 13 Apr 2005 at 16:46 GMT, J Krugman wrote:
>
>
> Is there a standard Unix utility that will print a specified range
> of lines? If I wanted to print, say, lines 81 through 100 of file
> foo, I'd use
>
> % head -100 foo | tail -20
>
> but I'm looking for some command, say bar, that would yield the
> same results without requiring a pipe, e.g.
>
> % bar 81,100 foo
>
> or something like this. (Actually, such a command would be a
> generalization of both head and tail.)

sed -n '81,100 p'

--
Chris F.A. Johnson http://cfaj.freeshell.org/shell
===================================================================
My code (if any) in this post is copyright 2005, Chris F.A. Johnson
and may be copied under the terms of the GNU General Public License

Ed Morton

unread,
Apr 13, 2005, 12:58:29 PM4/13/05
to

J Krugman wrote:

> Is there a standard Unix utility that will print a specified range
> of lines? If I wanted to print, say, lines 81 through 100 of file
> foo, I'd use
>
> % head -100 foo | tail -20
>
> but I'm looking for some command, say bar, that would yield the
> same results without requiring a pipe, e.g.
>
> % bar 81,100 foo
>
> or something like this. (Actually, such a command would be a
> generalization of both head and tail.)

sed -n '81,100p' foo

Ed.

David Weintraub

unread,
Apr 13, 2005, 5:00:27 PM4/13/05
to

J Krugman wrote:
> Is there a standard Unix utility that will print a specified range
> of lines? If I wanted to print, say, lines 81 through 100 of file
> foo, I'd use
>
> % head -100 foo | tail -20
>
> but I'm looking for some command, say bar, that would yield the
> same results without requiring a pipe, e.g.
>
> % bar 81,100 foo
>
> or something like this. (Actually, such a command would be a
> generalization of both head and tail.)

Most people gave you a sed solution. How about an awk solution?

$ awk 'NR >= 81 || NR <= 100' foo

The truth is that the sed solution is far more efficient, but I wanted
to show off.

Ed Morton

unread,
Apr 13, 2005, 5:10:23 PM4/13/05
to

Nice try, but it should be:

awk 'NR >= 81 && NR <= 100' foo

Ed.

Keith Thompson

unread,
Apr 13, 2005, 9:06:58 PM4/13/05
to
Ceri Davies <ceri_...@submonkey.net> writes:
> On 2005-04-13, J Krugman <jkrug...@yahbitoo.com> wrote:
>>
>>
>> Is there a standard Unix utility that will print a specified range
>> of lines? If I wanted to print, say, lines 81 through 100 of file
>> foo, I'd use
>>
>> % head -100 foo | tail -20
>>
>> but I'm looking for some command, say bar, that would yield the
>> same results without requiring a pipe, e.g.
>>
>> % bar 81,100 foo
>
> sed -n 81,100p < foo

Or sed -n 81,100p foo

Note that, unlike head, this will read the entire input, even if it
doesn't print it, which could be inefficient if foo is very large.
You can avoid this by telling sed to quit after reading line 100:

sed -n '81,100p;100q' foo

or, if you prefer:

sed -n -e 81,100p -e 100q foo

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

liljen...@gmail.com

unread,
Apr 14, 2005, 8:02:13 AM4/14/05
to

Note that any solutions using sed or awk to do the job of head and tail
will most probably be slower for long input, since they have to
evaluate a script for every line of input. Building pipelines and
creating a process are not very expensive operations under UNIX. If you
are just looking for a way to save keystrokes, create a script to
automate the task for you.

--
Axel

Ed Morton

unread,
Apr 14, 2005, 9:16:39 AM4/14/05
to

liljen...@gmail.com wrote:

> J Krugman wrote:
>
>>Is there a standard Unix utility that will print a specified range
>>of lines? If I wanted to print, say, lines 81 through 100 of file
>>foo, I'd use
>>
>> % head -100 foo | tail -20
>>
>>but I'm looking for some command, say bar, that would yield the
>>same results without requiring a pipe, e.g.
>>
>> % bar 81,100 foo
>>
>>or something like this. (Actually, such a command would be a
>>generalization of both head and tail.)
>>
>>Thanks!
>>
>>jill
>>
>>--
>>To s&e^n]d me m~a}i]l r%e*m?o\v[e bit from my a|d)d:r{e:s]s.
>
>
> Note that any solutions using sed or awk to do the job of head and tail
> will most probably be slower for long input, since they have to
> evaluate a script for every line of input.

On a 100,000 line file:

PS1> time head -100 big | tail -20 > /dev/null

real 0m0.111s
user 0m0.076s
sys 0m0.046s

PS1> time sed -n '81,100p;100q' big > /dev/null

real 0m0.062s
user 0m0.030s
sys 0m0.045s

PS1> time awk 'NR>100{exit}NR>80' big > /dev/null

real 0m0.039s
user 0m0.046s
sys 0m0.015s

PS1> time head -100000 big | tail -20 > /dev/null

real 0m0.601s
user 0m0.357s
sys 0m0.218s

PS1> time sed -n '81,100000p;100000q' big > /dev/null

real 0m2.821s
user 0m2.796s
sys 0m0.015s

PS1> time awk 'NR>100000{exit}NR>80' big > /dev/null

real 0m0.399s
user 0m0.358s
sys 0m0.046s

So, you have a point with sed only when the number of lines being
selected is large, but not at all with (g)awk. The above was using
Cygwin on Windows XP.

Ed.

Loki Harfagr

unread,
Apr 14, 2005, 9:19:24 AM4/14/05
to
Le Wed, 13 Apr 2005 16:10:23 -0500, Ed Morton a écrit :

...


>> Most people gave you a sed solution. How about an awk solution?
>>
>> $ awk 'NR >= 81 || NR <= 100' foo
>>
>> The truth is that the sed solution is far more efficient, but I wanted
>> to show off.
>>
>
> Nice try, but it should be:
>
> awk 'NR >= 81 && NR <= 100' foo
>
> Ed.

And yet showing off more if possible :-)

awk 'NR >= 81 ; NR == 100 {exit}' foo

(which adapts the remark made in a prev post
by Keith Thompson about not having to read the whole file )

Stephane CHAZELAS

unread,
Apr 14, 2005, 1:48:18 PM4/14/05
to
2005-04-14, 01:06(+00), Keith Thompson:
[...]

> sed -n '81,100p;100q' foo
>
> or, if you prefer:
>
> sed -n -e 81,100p -e 100q foo

or sed '81,$!d;100q' < foo

To avoid checking for the upper limit in the first expression.

--
Stéphane

Michael Tosch

unread,
Apr 14, 2005, 1:57:42 PM4/14/05
to
Ed Morton wrote:
>
>
...

>
> PS1> time head -100000 big | tail -20 > /dev/null
>
> real 0m0.601s
> user 0m0.357s
> sys 0m0.218s

Isnt this only 20 lines?
Please show us

time head -100000 big | tail -99920 > /dev/null

>
> PS1> time sed -n '81,100000p;100000q' big > /dev/null
>
> real 0m2.821s
> user 0m2.796s
> sys 0m0.015s
>
> PS1> time awk 'NR>100000{exit}NR>80' big > /dev/null
>
> real 0m0.399s
> user 0m0.358s
> sys 0m0.046s
>
> So, you have a point with sed only when the number of lines being
> selected is large, but not at all with (g)awk. The above was using
> Cygwin on Windows XP.
>
> Ed.
>


--
Michael Tosch @ hp : com

Ed Morton

unread,
Apr 14, 2005, 2:57:21 PM4/14/05
to

Michael Tosch wrote:
> Ed Morton wrote:

>> PS1> time head -100000 big | tail -20 > /dev/null
>>
>> real 0m0.601s
>> user 0m0.357s
>> sys 0m0.218s
>
>
> Isnt this only 20 lines?

Doh! Yes, you're right.

> Please show us
>
> time head -100000 big | tail -99920 > /dev/null

Here it is:

PS1> time head -100000 big | tail -99920 > /dev/null

real 0m0.611s
user 0m0.217s
sys 0m0.421s

Not much difference. Still much faster than sed but much slower than awk
for this example. By the way, I just tried this alternative form
Stephane posted for sed:

PS1> time sed '81,$!d;100000q' big > /dev/null

real 0m2.928s
user 0m2.890s
sys 0m0.062s

Regards,

Ed.

Keith Thompson

unread,
Apr 16, 2005, 6:21:36 AM4/16/05
to

Here's another one:

sed -n '81,$p;100q' foo

Note that if the sed command is at the end of a pipe, rather than
reading from a file, you might *want* to read and discard all the
input to avoid a SIGPIPE.

0 new messages