How to use sed to remove the last n lines of a file

LinuxBashShellSed

Linux Problem Overview


I want to remove some n lines from the end of a file. Can this be done using sed?

For example, to remove lines from 2 to 4, I can use

$ sed '2,4d' file

But I don't know the line numbers. I can delete the last line using

$sed $d file

but I want to know the way to remove n lines from the end. Please let me know how to do that using sed or some other method.

Linux Solutions


Solution 1 - Linux

I don't know about sed, but it can be done with head:

head -n -2 myfile.txt

Solution 2 - Linux

If hardcoding n is an option, you can use sequential calls to sed. For instance, to delete the last three lines, delete the last one line thrice:

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

Solution 3 - Linux

From the sed one-liners:

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

Seems to be what you are looing for.

Solution 4 - Linux

A funny & simple sed and tac solution :

n=4
tac file.txt | sed "1,$n{d}" | tac

NOTE

  • double quotes " are needed for the shell to evaluate the $n variable in sed command. In single quotes, no interpolate will be performed.
  • tac is a cat reversed, see man 1 tac
  • the {} in sed are there to separate $n & d (if not, the shell try to interpolate non existent $nd variable)

Solution 5 - Linux

Use sed, but let the shell do the math, with the goal being to use the d command by giving a range (to remove the last 23 lines):

sed -i "$(($(wc -l < file)-22)),\$d" file

To remove the last 3 lines, from inside out:

$(wc -l < file)

Gives the number of lines of the file: say 2196

We want to remove the last 23 lines, so for left side or range:

$((2196-22))

Gives: 2174 Thus the original sed after shell interpretation is:

sed -i '2174,$d' file

With -i doing inplace edit, file is now 2173 lines!

If you want to save it into a new file, the code is:

sed -i '2174,$d' file > outputfile

Solution 6 - Linux

You could use head for this.

Use

$ head --lines=-N file > new_file

where N is the number of lines you want to remove from the file.

The contents of the original file minus the last N lines are now in new_file

Solution 7 - Linux

Just for completeness I would like to add my solution. I ended up doing this with the standard ed:

ed -s sometextfile <<< $'-2,$d\nwq'

This deletes the last 2 lines using in-place editing (although it does use a temporary file in /tmp !!)

Solution 8 - Linux

To truncate very large files truly in-place we have truncate command. It doesn't know about lines, but tail + wc can convert lines to bytes:

file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file

There is an obvious race condition if the file is written at the same time. In this case it may be better to use head - it counts bytes from the beginning of file (mind disk IO), so we will always truncate on line boundary (possibly more lines than expected if file is actively written):

truncate -s $(head -n -$lines $file | wc -c) $file

Handy one-liner if you fail login attempt putting password in place of username:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure

Solution 9 - Linux

This might work for you (GNU sed):

sed ':a;$!N;1,4ba;P;$d;D' file

Solution 10 - Linux

Most of the above answers seem to require GNU commands/extensions:

    $ head -n -2 myfile.txt
    -2: Badly formed number

For a slightly more portible solution:

     perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'

OR

     perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'

OR

     awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'

Where "10" is "n".

Solution 11 - Linux

With the answers here you'd have already learnt that sed is not the best tool for this application.

However I do think there is a way to do this in using sed; the idea is to append N lines to hold space untill you are able read without hitting EOF. When EOF is hit, print the contents of hold space and quit.

sed -e '$!{N;N;N;N;N;N;H;}' -e x

The sed command above will omit last 5 lines.

Solution 12 - Linux

It can be done in 3 steps:

a) Count the number of lines in the file you want to edit:

 n=`cat myfile |wc -l`

b) Subtract from that number the number of lines to delete:

 x=$((n-3))

c) Tell sed to delete from that line number ($x) to the end:

 sed "$x,\$d" myfile

Solution 13 - Linux

You can get the total count of lines with wc -l <file> and use

head -n <total lines - lines to remove> <file>

Solution 14 - Linux

Try the following command:

n = line number
tail -r file_name | sed '1,nd' | tail -r

Solution 15 - Linux

This will remove the last 3 lines from file:

for i in $(seq 1 3); do sed -i '$d' file; done;

Solution 16 - Linux

I prefer this solution;

head -$(gcalctool -s $(cat file | wc -l)-N) file

where N is the number of lines to remove.

Solution 17 - Linux

To delete last 4 lines:

$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'   

Solution 18 - Linux

sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix version

Solution 19 - Linux

I came up with this, where n is the number of lines you want to delete:

count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt

It's a little roundabout, but I think it's easy to follow.

  1. Count up the number of lines in the main file
  2. Subtract the number of lines you want to remove from the count
  3. Print out the number of lines you want to keep and store in a temp file
  4. Replace the main file with the temp file
  5. Remove the temp file

Solution 20 - Linux

For deleting the last N lines of a file, you can use the same concept of

$ sed '2,4d' file

You can use a combo with tail command to reverse the file: if N is 5

$ tail -r file | sed '1,5d' file | tail -r > file

And this way runs also where head -n -5 file command doesn't run (like on a mac!).

Solution 21 - Linux

In docker, this worked for me:

head --lines=-N file_path > file_path

Solution 22 - Linux

#!/bin/sh

echo 'Enter the file name : '
read filename

echo 'Enter the number of lines from the end that needs to be deleted :'
read n

#Subtracting from the line number to get the nth line
m=`expr $n - 1`

# Calculate length of the file
len=`cat $filename|wc -l`

#Calculate the lines that must remain
lennew=`expr $len - $m`

sed "$lennew,$ d" $filename

Solution 23 - Linux

A solution similar to https://stackoverflow.com/a/24298204/1221137 but with editing in place and not hardcoded number of lines:

n=4
seq $n | xargs -i sed -i -e '$d' my_file

Solution 24 - Linux

Say you have several lines:

    $ cat <<EOF > 20lines.txt
> 1
> 2
> 3
[snip]
> 18
> 19
> 20
> EOF

Then you can grab:

# leave last 15 out
$ head -n5 20lines.txt
1
2
3
4
5

# skip first 14
$ tail -n +15 20lines.txt
15
16
17
18
19
20

Solution 25 - Linux

This will remove the last 12 lines

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmezdaView Question on Stackoverflow
Solution 1 - LinuxamsView Answer on Stackoverflow
Solution 2 - LinuxKyleView Answer on Stackoverflow
Solution 3 - LinuxqstebomView Answer on Stackoverflow
Solution 4 - LinuxGilles QuenotView Answer on Stackoverflow
Solution 5 - LinuxlzcView Answer on Stackoverflow
Solution 6 - LinuxrichardView Answer on Stackoverflow
Solution 7 - LinuxMichelView Answer on Stackoverflow
Solution 8 - LinuxKamil ChristView Answer on Stackoverflow
Solution 9 - LinuxpotongView Answer on Stackoverflow
Solution 10 - Linuxuser1170868View Answer on Stackoverflow
Solution 11 - LinuxRishabh SagarView Answer on Stackoverflow
Solution 12 - LinuxRey LefebvreView Answer on Stackoverflow
Solution 13 - LinuxSWW13View Answer on Stackoverflow
Solution 14 - LinuxRishav KaushalView Answer on Stackoverflow
Solution 15 - Linuxuser5780554View Answer on Stackoverflow
Solution 16 - Linuxp014kView Answer on Stackoverflow
Solution 17 - LinuxmstafreshiView Answer on Stackoverflow
Solution 18 - LinuxNeronLeVeluView Answer on Stackoverflow
Solution 19 - LinuxcoyotetechyView Answer on Stackoverflow
Solution 20 - LinuxAlessandra BilardiView Answer on Stackoverflow
Solution 21 - LinuxJRichardszView Answer on Stackoverflow
Solution 22 - LinuxSherlock HolmesView Answer on Stackoverflow
Solution 23 - LinuxZacView Answer on Stackoverflow
Solution 24 - Linuxuser2928048View Answer on Stackoverflow
Solution 25 - LinuxR. KumarView Answer on Stackoverflow