Add line after last match with sed

Suppose I have the following input.

Header
thing0 some info
thing4 some info
thing4 some info
thing4 some info
thing2 some info
thing2 some info
thing3 some info

Now I want to add “foo” to the last successful match of “thing4” like this.

Header
thing0 some info
thing4 some info
thing4 some info
thing4 some info
foo
thing2 some info
thing2 some info
thing3 some info

The order is not necessarily guaranteed, but the sequential numbering in this example is just to show that some lines of text have a search keyword in front of them, and that they are usually grouped together in the input, but this is not guaranteed.

+10
source share
6 answers

Using one awk, you can do:

awk 'FNR==NR{ if (/thing4/) p=NR; next} 1; FNR==p{ print "foo" }' file file

Header
thing0 some info
thing4 some info
thing4 some info
thing4 some info
foo
thing2 some info
thing2 some info
thing3 some info

Previous solution: You can use tac + awk + tac:

tac file | awk '!p && /thing4/{print "foo"; p=1} 1' | tac
+4
source

This may work for you (GNU sed):

sed '1h;1!H;$!d;x;s/.*thing4[^\n]*/&\nfoo/' file

, .

( ), :

sed '/thing4[^\n]*/,$!b;//{x;//p;g};//!H;$!d;x;s//&\nfoo/' file

.

+3

, . @anubhava, tac flip append, , . .

tac | sed '0,/thing4/s/thing4/foo\n&/' | tac

+1

,

awk 'BEGIN{RS="^$"}
        {$0=gensub(/(.*thing4[^\n]*\n)/,"\\1foo\n","1",$0);printf "%s",$0}' file

Header
thing0 some info
thing4 some info
thing4 some info
thing4 some info
thing2 some info
thing2 some info
thing3 some info

Header
thing0 some info
thing4 some info
thing4 some info
thing4 some info
foo
thing2 some info
thing2 some info
thing3 some info


  • RS , .. ^$, .

  • .*thing4[^\n]*\n gensub , thing4.

  • gensub \1. , \, \\1foo\n. \n escape-, n.



  • gnu-awk, .
  • , , nbd , .
+1

, . , awk :

awk -v s=thing3 -v t=foo 'END{if(f) print t} {if($0~s)f=1; else if(f) {print t; f=0}}1' file

awk -v s=thing0 -v t=foo 'END{if(f)print t} {f=$0~s} f,!f{if(!f)print t}1' file
+1
source
sed -e "$(grep -n 'thing4' file |tail -1|cut -f1 -d':')a foo" file

Use shell and grep to get the number of the last line containing the pattern, then use that number as the address for the sed append command.

0
source

All Articles