Reputation: 29
I have the following XML:
<xml>
<bean id="bean1"
class="class1"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<!-- <property name="MyProperty" value="5000"/> -->
</bean>
<bean id="bean2"
class="class2"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<!-- <property name="MyProperty" value="5000"/> -->
</bean>
<bean id="bean3"
class="class3"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<!-- <property name="MyProperty" value="5000"/> -->
</bean>
</xml>
I need to uncomment the element:
<!-- <property name="MyProperty" value="5000"/> -->
Only inside bean with id "bean3". Then I need to modify its value, so that it is 50 instead of 5000.
I have tried using the following command:
grep -A 4 "bean3" file.xml | sed 's/<!--//' | sed 's/-->//' | sed 's/5000/50/'
But I am not able to replace it in file.
Should I use sed and/or grep?
Upvotes: 1
Views: 2045
Reputation: 203254
$ awk '/<bean id=/{f=(/bean3/?1:0)} f&&gsub(/<!-- *| *-->/,""){sub(/00/,"")} 1' file
<xml>
<bean id="bean1"
class="class1"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<!-- <property name="MyProperty" value="5000"/> -->
</bean>
<bean id="bean2"
class="class2"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<!-- <property name="MyProperty" value="5000"/> -->
</bean>
<bean id="bean3"
class="class3"
singleton="false">
<property name="dbPoolName" value="pool"/>
<property name="dirName" value="myDir"/>
<property name="MyProperty" value="50"/>
</bean>
</xml>
Upvotes: 0
Reputation: 7161
Here is an AWK script that scans for the bean
tag with id="bean3"
and uncomments and changes "5000"
to "50"
until the next bean
tag:
#!/usr/bin/awk
BEGIN{ in_bean3 = 0 }
$0~/<bean / { # match start of bean tag
if ( $0 ~ "id=\"bean3\"" ) {
# Set flag for desired context
in_bean3 = 1
print
next
} else { # clear flag
in_bean3 = 0
}
}
in_bean3 { # in desired context
sub(/<!-- */, "")
sub(/ *-->/, "")
sub(/"5000"/, "\"50\"")
}
1
Notice the 1
at the end performs the default action of printing the line.
Upvotes: 0
Reputation: 11983
If you’re using GNU sed, you can do it all with one command:
sed '/bean3/,+5s/<!-- *\|-->//g; /bean3/,+5s/5000/50/' file.xml
You only need to run one instance of the sed
command. Individual sed commands are separated with a semicolon, ;
. In this case, we only needed two sed commands:
<!--
(optionally followed by spaces) and -->
with an empty string – using the alternation \|
operator and the g
(global) modifier.5000
with 50
.The /bean3/,+5
range is a GNU extension; this ensures that the above substitutions are only performed on the 5 lines following the first occurrence of bean3
. This range is used for both substitution commands.
If you’re confident that the sed commands do what you want, you can use the -i
/ --in-place
option to change file.xml
.
Upvotes: 3