Ferry Mulia
Ferry Mulia

Reputation: 23

sed replace multiple xml tag

I need to replace multiple lines in xml file using sed. here is my input file:

<firstTag>Y</firstTag>
<secondTag/>

I want to replace those line into below format:

<firstTag></firstTag>
<secondTag>Y</secondTag>

I tried using this command:

sed -i -r "s#<firstTag>Y</firstTag>\n.*#<firstTag></firstTag>\n<secondTag>Y</secondTag>#g" input.txt

But it is not working. I also notice there are some tab (^I using less command) before the secondTag. Will it affect the sed command? Please help me about this.

Update: There are multiple occurance of secondTag in the file and I only want to change the secondTag value to Y only after it find that previous value of firstTag is Y. For example, if in input.txt:

<firstTag>Y</firstTag>
<secondTag/>
<firstTag/>
<secondTag/>

I want it to be replaced into:

<firstTag></firstTag>
<secondTag>Y</secondTag>
<firstTag/>
<secondTag/>

Upvotes: 2

Views: 5672

Answers (4)

sat
sat

Reputation: 14949

You can try this sed:

sed -r '/<firstTag>.*<\/firstTag>/{N;s#(<firstTag>)(.*)((</firstTag>\n)<secondTag/>)#\1\4<secondTag>\2</secondTag>#g}' file.txt

Upvotes: 1

Jotne
Jotne

Reputation: 41456

Using awk you can do this:

awk -F"[<>/]" '/^<firstTag>/ {f=$3;$0="<"$2"></"$2">"} /^<secondTag\/>/ {$0="<"$2">" f "</"$2">"}1' file
<firstTag><firstTag/>
<secondTag>Y</secondTag>

Regarding this comment:

sorry, I forgot to mention that there are multiple occurance of secondTag and I only want to change the secondTag value to Y only after it find that previous value of firstTag is Y

Here is another awk that only change the first secondTag if there is a firstTag, ignore all other:

cat file
<secondTag/>
<firstTag>Y</firstTag>
<secondTag/>
<someOtherTag>
<secondTag/>

The awk

awk -F"[<>/]" '/^<firstTag>/ {f=$3;$0="<"$2"></"$2">"} f && /^<secondTag\/>/ {$0="<"$2">" f "</"$2">";f=""}1' file
<secondTag/>
<firstTag></firstTag>
<secondTag>Y</secondTag>
<someOtherTag>
<secondTag/>

Upvotes: 1

potong
potong

Reputation: 58430

This might work for you (GNU sed):

sed -r '$!N;s|^(<firstTag>)Y(</firstTag>\n<(secondTag))/>$|\1\2>Y</\3>|;P;D' file

Upvotes: 2

Sean Johnson
Sean Johnson

Reputation: 5607

What about seperating the two tag replacements?

sed -i -r -e "s#<firstTag>Y</firstTag>#<firstTag></firstTag>#" -e "s#<secondTag/>#<secondTag>Y</secondTag>#" input.txt

Upvotes: 0

Related Questions