Match pattern1 in file, match pattern2, substitute value1 in line

not getting anywhere with this

an xml file contains multiple clients set up with same tags, different values.

I need to parse the file for client foo, and change the value of tag "64bit" from false to true.

cat clients.xml

<Client type"FIX">
<ClientName>foo</ClientName>
<ListeningPort>999</ListeningPort>
<SCompID>bar</SCompID>
<TCompID>baz</TCompID>
<MsgP>Alice</MsgP>
<Trace>true</Trace>
<Session type="NATIVE"/>
<64bit>false</64bit>
</Client>

<Client type"FIX">
<ClientName>alice</ClientName>
<ListeningPort>991</ListeningPort>
<SCompID>bar2</SCompID>
<TCompID>baz2</TCompID>
<MsgP>Alice</MsgP>
<Trace>true</Trace>
<Session type="NATIVE"/>
<64bit>false</64bit>
</Client>

i have so far only managed to output the 7 lines below my pattern, last one of which is the one i need to work on

bash-3.2$ cat clients.xml|awk 'a-->0;/ClientName.foo/{a=7}'
<ListeningPort>999</ListeningPort>
<SCompID>bar</SCompID>
<TCompID>baz</TCompID>
<MsgP>Alice</MsgP>
<Trace>true</Trace>
<Session type="NATIVE"/>
<64bit>false</64bit>

other method i am looking at is using sed

sed -r -e '/Name.foo/ { n ; s/false/true/ }' clients.xml

how can i move to the 7th line instead of next line

Try the awk script below...

awk '/^<ClientName>foo<\/ClientName>$/,/^<\/Client>$/ {if($0 ~ "^<64bit>false</64bit>$") $0="<64bit>true</64bit>";print}' clients.xml
1 Like

That approach would work fine if it were modified to use the correct number of consecutive n commands.

That sed script does not require -r .

Regards,
Alister

1 Like

works, thanks. had to tweak a little though

awk '/Name.foo/,/64bit/ {if($0 ~ "<64bit>false<\/64bit>") $0="<64bit>true<\/64bit>";print}' clients.xml

also came up with this that equally works

sed '/Name.foo/,/64bit/ s/64bit>false/64bit>true/'