Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I discard the last n lines of a file with a unix command line filter?

That would be sort of the opposite of tail: tail discards the first n lines but pipes the rest through, but I want the command to pipe everything through except the last n lines.

Unfortunately I haven't found anything like that - head doesnt help, too. EDIT: At least in Solaris it does not take negative arguments.

share|improve this question
FYI when using head: By placing ‘-’ in front of the number with -n option, it prints all the lines of each file but not the last N lines as shown below, – G Koe Jan 30 '13 at 13:46
up vote 13 down vote accepted

If you have GNU head, you can use

head -n -5 file.txt

to print all but the last 5 lines of file.txt.

If head -n takes no negative arguments, try

head -n $(( $(wc -l file.txt | awk '{print $1}') - 5 )) file.txt
share|improve this answer
(and pray that file.txt is at least six lines long...) – Michael Kjörling Jan 30 '13 at 14:59
Sadly this non-GNU version doesn't work with streams, either – Alison Apr 6 at 10:58

I'm curious why you think head is not an option:

~$ man 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

This seems to fit your purpose, using, for example:

head -n -20 yourfile.txt
share|improve this answer
Note that this only applies to GNU head. BSD head doesn't have this option, so this answer will not work on Solaris or other Unixes without GNU coreutils. The OP specifically tagged this with Unix and Unix-Utils too. – slhck Jan 30 '13 at 14:06
@slhck Not to mention the fact that the OP mentioned that this is for Solaris. – Michael Kjörling Jan 30 '13 at 15:00
Unfortunately someone removed my mention of Solaris. But I should have mentioned anyway that the version of head does not support that. – hstoerr Jan 30 '13 at 16:47
Sorry all. Did not notice Solaris, nor was I aware of the various versions of head. – Anders R. Bystrup Jan 30 '13 at 18:00
@hstoerr Solaris is now in your tags :) – slhck Jan 30 '13 at 19:50

Here's a simple way to delete the last line, which works on BSD, etc.

sed '$d' input.txt

The expression reads "on the last line, delete it". The other lines will be printed, since that is sed's default behavior.

You could chain them together to remove multiple lines

sed '$d' input.txt | sed '$d' | sed '$d'

Which is a little heavy-handed, admittedly, but does only one scan through the file.

You can also take a look at this, for more answers:

Here's a one-liner adapted from one of my favorites there:

sed -n -e ':a' -e "1,$N!{P;N;D;};N;ba"

I had fun deciphering that one, and I hope you do, too (: It does buffer N lines as it scans, but otherwise is pretty efficient.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .