Shell – Negative arguments to head / tail

headoptionsosxshell-scripttail

Variants of this question have certainly been asked several times in different places, but I am trying to remove the last M lines from a file without luck.

The second most voted answer in this question recommends doing the following to get rid of the last line in a file:

head -n -1 foo.txt > temp.txt

However, when I try that in OSX & Zsh, I get:

head: illegal line count -- -1

Why is that? How can I remove the M last lines and the first N lines of a given file?

Best Answer

You can remove the first 12 lines with:

tail -n +13

(That means print from the 13th line.)

Some implementations of head like GNU head support:

head -n -12

but that's not standard.

tail -r file | tail -n +12 | tail -r

would work on those systems that have tail -r (see also GNU tac) but is sub-optimal.

Where n is 1:

sed '$d' file

You can also do:

sed '$d' file | sed '$d'

to remove 2 lines, but that's not optimal.

You can do:

sed -ne :1  -e 'N;1,12b1' -e 'P;D'

But beware that won't work with large values of n with some sed implementations.

With awk:

awk -v n=12 'NR>n{print line[NR%n]};{line[NR%n]=$0}'

To remove m lines from the beginning and n from the end:

awk -v m=6 -v n=12 'NR<=m{next};NR>n+m{print line[NR%n]};{line[NR%n]=$0}'
Related Question