I have some text containing identifiable blocks of text stored in a variable $mytext:
start
This is my house and I can see my car from it.
This is my dog and it dislikes squirrels.
end
start
This is my car and I can see my house from it.
This is my dog and it dislikes squirrels.
end
I want to replace just the first "my" with "our" in each block from "start" to "end" so that I end up with
start
This is our house and I can see my car from it.
This is my dog and it dislikes squirrels.
end
start
This is our car and I can see my house from it.
This is my dog and it dislikes squirrels.
end
So what I've got is the following:
sed -zE "/start/, /end/ s/my/our/1;q" <<< $mytext
but this will only replace just the first "my" in the first block and ignores the "my" in the second block. I think that this is because it is finding the first "start" and the last "end" and so only doing the replace once.
Of course the text in $mytext is a much simpler version of what I'm actually trying to do but it is there to illustrate the point.
How do I replace both first instances of "my" in the two blocks without leaving bash?
CodePudding user response:
If you want to give awk
a chance then use:
awk 'p==1 {p = sub(/my/, "our")} /^start$/ {p=1} /^end$/ {p=0} 1' file
start
This is our house and I can see my car from it.
This is my dog and it dislikes squirrels.
end
start
This is our car and I can see my house from it.
This is my dog and it dislikes squirrels.
end
CodePudding user response:
With sed
first replace the my
string by an unique character.
Next a "normal" sed
command where you you replace the first unique character after start
.
And now restore the remaining temp characters with the original value.
sed -zE 's/ my /\r/g;s/(start[^\r]*)\r/\1 our /g;s/\r/ my /g' file