0

I have an XML file (config.xml) as below.

<?xml version="1.1" encoding="UTF-8"?>
  <project>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
   <triggers>
    <com.cloudbees.jenkins.GitHubPushTrigger plugin="github@1.29.2">
      <spec/>
    </com.cloudbees.jenkins.GitHubPushTrigger>
   </triggers>
   <concurrentBuild>false</concurrentBuild>
  </project>

I want to replace the triggers block with only <triggers/>. But when I use SED to do it, I get this error:

sed: 1: "/<triggers>/{:a;N;/<\/t ...": unexpected EOF (pending }'s)

Command:

sed -i '.bak' '/<triggers>/{:a;N;/<\/triggers>/!ba;N;s/.*\n/<triggers\/>\n/};p' config.yml

I want you to know what am I missing here and how to get the desired outcome?

Desired Output:

<?xml version="1.1" encoding="UTF-8"?>
<project>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
</triggers>
<concurrentBuild>false</concurrentBuild>
</project>
Aki
  • 179
  • 2
  • 14
  • 3
    [You can't parse \[X\]HTML with regex](http://stackoverflow.com/a/1732454/3776858). I suggest to use an XML/HTML parser (xmlstarlet, e.g.). – Cyrus Jul 14 '18 at 06:45
  • You mean you actually want to produce invalid XML output, containing an end tag with no matching start tag? That's a pretty weird requirement... – Michael Kay Jul 14 '18 at 09:43
  • This should work in your case, but **I don't recommend it**: `sed -e '//,/<\/triggers>/{/<\/triggers>/{i \ \ ' -e '};d}' file.xml` – Cyrus Jul 15 '18 at 06:46
  • I have edit the question, realized it later. Modified it to get valid XML. When I run: `sed -e '//,/<\/triggers>/{/<\/triggers>/{i \ \ ' -e '};d}' file.xml` Output: `sed: 1: "//,/<\/trigge ...": extra characters after \ at the end of i command` – Aki Jul 16 '18 at 14:27

1 Answers1

2

With this valid XML file:

<?xml version="1.0"?>
<root>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
    <com.cloudbees.jenkins.GitHubPushTrigger plugin="github@1.29.2">
      <spec/>
    </com.cloudbees.jenkins.GitHubPushTrigger>
  </triggers>
  <concurrentBuild>false</concurrentBuild>
</root>

With this command:

xmlstarlet edit --omit-decl --update "//triggers" --value ""

Output:

<root>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
</root>

If you want to edit file inplace, add option -L.


See: xmlstarlet edit --help

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • I get this strange error with inline option: `xmlstarlet edit -L --update "//triggers" --value "" config.xml config.xml:1.20: Unsupported version '1.1' ` It doesn't seem to like the XML version. – Aki Jul 14 '18 at 07:06
  • It looks like your xmlstarlet does not support XML version 1.1. – Cyrus Jul 14 '18 at 07:09
  • And the other problem I am facing is, production servers don't have `xmlstarlet` installed. That is the reason I am stuck with SED. I went through a lot of questions here before posting mine. – Aki Jul 14 '18 at 07:09