Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a line before the FIRST and LAST matching pattern using sed

I have a file: users.txt that looks like the below:

    Surname
    Surname
    Surname
    Age
    Age
    Age

I need to add ONE line with text: Name ABOVE wherever I find the FIRST occurrence of Surname so that the file looks like:

    Name
    Surname
    Surname
    Surname
    Age
    Age
    Age

I also need to be able to add ONE line with text: Gender BELOW wherever I find the LAST occurrence of Age so that the file looks like:

    Surname
    Surname
    Surname
    Age
    Age
    Age
    Gender

Currently I have these sed commands:

sed '/Surname/i \Name' user.txt
sed '/Age/a \Gender' users.txt

Though they are adding in new lines on EVERY match found.

Your time and assistance is greatly appreciated.

like image 849
FireHawk2300 Avatar asked Oct 16 '25 13:10

FireHawk2300


2 Answers

awk would be easier. Whenever I hear "do something on the LAST ..." I think "reverse the file, and do something on the FIRST ..."

file=users.txt
tmpfile=$(mktemp)

tac "$file" | 
awk '/Age/ && !found {print "Gender"; found=1} 1' | 
tac | 
awk '/Surname/ && !found {print "Name"; found=1} 1' > "$tmpfile" &&
mv "$tmpfile" "$file"

actually the sed is not that atrocious:

sed '
  /Surname/ {
    # we have seen the first pattern, insert the 1st new line
    i Name
    :a
    N                         # append the next line to pattern space
    $ {                       # if this is the last line
      s/.*Age\n/&Gender\n/    # add the 2nd new line after the last Age
      bb                      # and we are done: goto b
    }
    ba                        # goto a
    :b
  }
' users.txt 
like image 124
glenn jackman Avatar answered Oct 18 '25 08:10

glenn jackman


Example how to do it in Perl

perl -nE'/Surname/&&($n++||say"Name")||($n=0);/Age/&&($g=1)||($g--&&say"Gender");print}{say"Gender"if$g'

And another way

perl -nE'/Surname/&&say("Name")..!/Surname/;/Age/&&($g=1)||($g--&&say"Gender");print}{say"Gender"if$g'
like image 24
Hynek -Pichi- Vychodil Avatar answered Oct 18 '25 08:10

Hynek -Pichi- Vychodil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!