3

I have a file.txt and I have to delete the second-to-last line of the file. The below three sed commands are able to print the second-to-last line. But I need to delete that line. Any help??

sed -e '$!{h;d;}' -e x file.txt

sed -n 'x;$p' file.txt

sed 'x;$!d' file.txt

$ cat file.txt
apple
pears
banana
carrot
berry

Can we delete the second-to-last line of a file:
a. not based on any string/pattern.
b. based on a pattern - if second-to-last line contains "carrot"

Arun
  • 105
  • 2
  • 5

2 Answers2

5

This might work for you (GNU sed):

sed -i 'N;$!P;D' file

This sets up a window of two lines in the pattern space and then prints the first of those whenever the second is not the last. The last line is always printed because the next line can not be fetched.

Deleting the second-to-last line of a file based on a pattern can be achieved with:

sed -i 'N;$!P;${/pattern.*\n/!P};D'
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
potong
  • 55,640
  • 6
  • 51
  • 83
  • Potong, Just tested it, it prints the output without the second-to-last line but the line did not get deleted in the actual file. – Arun Jul 20 '16 at 18:02
  • 1
    @Arun you must add the `-i` option to update the file inline. See edit. – potong Jul 20 '16 at 18:04
  • Potong, it works. Would you be able to explain the 'N;$!P;D' part? – Arun Jul 20 '16 at 18:25
  • @Arun Hover your cursor over the `sed` tag you will find much more information there. Sed is a line editor, so it reads a line at a time into a register called the pattern space (PS) (any newline is removed first). `N` command appends the next line (separated by a newline) to the PS. `$` is an address for the last line of the file. `!` negates the previous address or pattern, so `$!` means not the last line. `P` prints from the start of the PS to and includind any newline. `D` deletes what `P` matches then transfers control to the first command unless PS is empty when a new cycle is started. – potong Jul 20 '16 at 19:28
  • Thank you for the explanation. If D is for deleting, would you be able to tell what is for replacing a pattern with another string in the next-to-last line (above example)? – Arun Jul 28 '16 at 22:16
5

I know this is an old question, but as I've not seen what I use, I'll add it in case it helps.

Combining sed with tac makes this very easy:

mv file.txt file.txt.bak
tac file.txt.bak | sed '2d' | tac > file.txt

This would remove the second-to-last line of the file. It's not a "pure" sed solution, and it needs an intermediate file, but I use it often because IMHO it's easier to understand.

rsuarez
  • 179
  • 2
  • 4