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.
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
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With