Tail inverse / printing everything except the last n lines?

Is there a (POSIX command line) way to print all of a file EXCEPT the last n lines? Use case being, I will have multiple files of unknown size, all of which contain a boilerplate footer of a known size, which I want to remove. I was wondering if there is already a utility that does this before writing it myself.


Solution 1:

Most versions of head(1) - GNU derived, in particular, but not BSD derived - have a feature to do this. It will show the top of the file except the end if you use a negative number for the number of lines to print.

Like so:

head -n -10 textfile

Solution 2:

Probably less efficient than the "wc" + "do the math" + "tail" method, but easier to look at:

tail -r file.txt | tail +NUM | tail -r

Where NUM is one more than the number of ending lines you want to remove, e.g. +11 will print all but the last 10 lines. This works on BSD which does not support the head -n -NUM syntax.

Solution 3:

The head utility is your friend.

From the man page of head:

-n, --lines=[-]K
     print the first K lines instead of the first 10;
       with the leading `-', print all but the last K lines of each file

Solution 4:

There's no standard commands to do that, but you can use awk or sed to fill a buffer of N lines, and print from the head once it's full. E.g. with awk:

awk -v n=5 '{if(NR>n) print a[NR%n]; a[NR%n]=$0}' file

Solution 5:

cat <filename> | head -n -10 # Everything except last 10 lines of a file
cat <filename> | tail -n +10 # Everything except 1st 10 lines of a file