Gentoo Development Guide

head-and-tail -- Line Extraction

The head and tail utilities can be used to obtain only the first or last parts of a file respectively. Both will read from the files named on the commandline, or stdin if no files are provided.

The head utility takes a single argument, -n, which must be followed by an integer indicating the desired number of lines to be displayed.

Warning

Use of the GNU -c option is unportable and should be avoided.

For full details, see IEEE1003.1-2004-head. Note that head-1 on GNU systems describes many non-portable options.

The tail utility is similar, but takes lines from the end of the file. The -n argument specifies how many lines to display.

To specify "the last five lines", use tail -n5. To specify "all but the first five lines", use tail -n+5.

Warning

head/tail -5 syntax is deprecated and not POSIX compliant.

For full details, see IEEE1003.1-2004-tail. Note that tail-1 on GNU systems describes many non-portable options.

Chaining with head or tail with sed

Chaining head or tail with sed is usually unnecessary. Use of addresses and early exit can do the same thing with a single sed call:

# bad: get the first five lines of input.txt with all 'foo'
# replaced with 'bar'
head -n 5 input.txt | sed -e 's/foo/bar/g' > output.txt

# good: use sed's address ranges and command groups to do
# the same thing with only one fork
sed -n -e '1,5{ s/foo/bar/g ; p }' input.txt > output.txt

# good: another way is with an extra command which exits
# on line 5
sed -n -e 's/foo/bar/gp ; 5q' input.txt > output.txt

# bad: set foo to the first line containing somestring
foo=$(sed -n -e '/somestring/p' input.txt | head -n 1 )

# good: use early exit to do the same thing in pure sed
foo=$(sed -n -e '/somestring/{ p ; q }' input.txt )

# bad: output the last line matching 'somestring'
sed -n -e '/somestring/p' input.txt | tail -n 1

# good: do this in pure sed using the hold space
sed -n -e '/somestring/h ; $ {x;p}'

tail -n X where X is larger than one is possible to do in pure sed but tricky. Using chained commands here is probably simplest.

Finally, to extract a single specific line, use sed instead:

sed -n -e '123p'