Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete all the lines after the last occurence of pattern?

Tags:

bash

sed

awk

i want to delete all the lines after the last occurence of pattern except the pattern itself

file.txt

honor
apple
redmi
nokia
apple
samsung
lg
htc

file.txt what i want

honor
apple
redmi
nokia
apple

what i have tried

sed -i '/apple/q' file.txt

this deletes all the line after the first occurence of pattern -

honor
like image 644
j.doe Avatar asked Jun 01 '17 13:06

j.doe


People also ask

How do I delete everything after a character in bash?

In Bash (and ksh, zsh, dash, etc.), you can use parameter expansion with % which will remove characters from the end of the string or # which will remove characters from the beginning of the string. If you use a single one of those characters, the smallest matching string will be removed.


Video Answer


3 Answers

Simple, robust 2-pass approach using almost no memory:

$ awk 'NR==FNR{if (/apple/) hit=NR; next} {print} FNR==hit{exit}' file file
honor
apple
redmi
nokia
apple

If that doesn't execute fast enough THEN it's time to try some alternatives to see if any produce a performance improvement.

like image 148
Ed Morton Avatar answered Oct 19 '22 18:10

Ed Morton


Reverse the file, print everything starting from the first occurrence of the pattern, then reverse the result:

tac file.txt | sed -n '/apple/,$p' | tac > newfile.txt

You can find the line number of the last match, then use that to print the first N lines of the file:

line=$(awk '/apple/ { line=NR } END {print line}')
head -n $line file.txt > newfile.txt
like image 33
Barmar Avatar answered Oct 19 '22 17:10

Barmar


If you don't want to reverse the file as Barmar suggests, you will either have to read the file in reverse using lower level tools (eg, fseek) or read it twice:

sed $(awk '/apple/{a=NR}END{print a+1}' input),\$d input

(Note that if the pattern does not appear in the file, this will output nothing. That's an edge case you should worry about.)

like image 44
William Pursell Avatar answered Oct 19 '22 17:10

William Pursell