Reputation: 1
Imagine I have the following piece of text:
<Data>
<Country>
<Name>Portugal<\Name>
<Population>10M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
<Country>
<Name>Spain<\Name>
<Population>30M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
</Data>
How can I replace the Y
to N
from Country Portugal without replacing the Code from the remaining countries?
I've tried to use sed:
sed -i '/<Country>Portugal<\/Country>/{s/Y/N/;}' file.xml
but this is not replacing anything.
Can you tell me what I am doing wrong? How can I replace the first occurrence of Y
AFTER matching the Portugal ?
Thanks!
Upvotes: 0
Views: 267
Reputation: 204628
If your input is really always exactly that format then all you need is:
$ awk '/<Name>/{f=/Portugal/} f && /<Code>/{sub(/Y/,"N")} 1' file
<Data>
<Country>
<Name>Portugal<\Name>
<Population>10M</Population>
<Sub>
<Code>N</Code>
</Sub>
</Country>
<Country>
<Name>Spain<\Name>
<Population>30M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
</Data>
Upvotes: 0
Reputation: 15438
Use a range match.
sed '/<Name>Portugal</,/<\/Country>/ s/<Code>Y</<Code>N</' file.xml
(Edited to match updated requirements.)
Upvotes: 0
Reputation: 58578
This might work for you (GNU sed):
sed '/<Country>/{:a;N;/<\/Country>/!ba;/Portugal/s/Y/N/}' /file
Gather up the lines for a Country
then match those lines to contain Portugal
and replace the first Y
with N
.
Upvotes: 0
Reputation: 123690
Avoid parsing XML with regex. Use an XML processing tool like xmlstarlet
:
$ cat foo.xml
<Data>
<Country>
<Name>Portugal</Name>
<Population>10M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
<Country>
<Name>Spain</Name>
<Population>30M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
</Data>
$ xmlstarlet edit --update '/Data/Country[Name="Portugal"]/Sub/Code' -v "N" foo.xml
<?xml version="1.0"?>
<Data>
<Country>
<Name>Portugal</Name>
<Population>10M</Population>
<Sub>
<Code>N</Code>
</Sub>
</Country>
<Country>
<Name>Spain</Name>
<Population>30M</Population>
<Sub>
<Code>Y</Code>
</Sub>
</Country>
</Data>
Upvotes: 2