1

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?

2
  • grep will extract only lines matching a pattern. The rest are removed. In this case, you want to keep all the other lines too. But the restriction that you only want to modify the bean tags with id="bean3" complicates things. I would suggest using something that actually parses XML, but it might not pick up the comments. Commented Jan 22, 2016 at 20:16
  • might be a duplicate of stackoverflow.com/q/784745/7552 Commented Jan 22, 2016 at 22:10

3 Answers 3

3

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:

  1. The first substitutes both <!-- (optionally followed by spaces) and --> with an empty string – using the alternation \| operator and the g (global) modifier.
  2. The second simply replaces 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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0
$ 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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.