-1

I'm New in bash scripting.

I have xml tabs in file alpha.xml, as

<tab>
<enabled>false</enabled>
</tab>
<tabToChange>
<enabled>false</enabled>
</tabToChange >

I'm trying to change this to

<tab>
<enabled>false</enabled>
</tab>
<tabToChange>
<enabled>true</enabled>
</tabToChange >

referencing with https://unix.stackexchange.com/questions/26284/how-can-i-use-sed-to-replace-a-multi-line-string

I tried command as

sed '/^tabToChange$/ {N; s/\<tabToChange\>n\<enabled\>/yo/g}' alpha.txt
sed '/^\<<tabToChange>\>$/ {N; s/\<<tabToChange>\>\n\<enabled\>/yo/g}' alpha.txt
sed '/^\<\<tabToChange\>\>$/ {N; s/\<\<tabToChange\>\>\n\<\<enabled\>\>/yo/g}' alpha.txt

None of them works. Could someone please help me

Neil
  • 2,714
  • 11
  • 29
  • 45
  • show the parent tag which contains those you have posted. I mean there should the "root" tag for valid xml structure – RomanPerekhrest May 05 '17 at 17:14
  • 2
    Use an xml parser not regex. – 123 May 05 '17 at 17:19
  • Concur with @123, any regex-based approach is likely to be hit-or-miss. Some nice command-line xml tool recommendations here: http://stackoverflow.com/questions/91791/grep-and-sed-equivalent-for-xml-command-line-processing – Vasan May 05 '17 at 17:21

3 Answers3

2

To manipulate XML documents use XML parsers/tools.
I would use xmlstarlet tool. Supposing that input XML data is enclosed in parent <root> tag (you'll have your own tag):

<root>
<tab>
<enabled>false</enabled>
</tab>
<tabToChange>
<enabled>false</enabled>
</tabToChange >
</root>

The command:

xmlstarlet ed -u "//tabToChange/enabled" -v true alpha.xml

The output:

<?xml version="1.0"?>
<root>
  <tab>
    <enabled>false</enabled>
  </tab>
  <tabToChange>
    <enabled>true</enabled>
  </tabToChange>
</root>

ed - edit mode

-u - to update value

"//tabToChange/enabled" - xpath expression to match the needed element

-v true - the value to be set

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

I agree with the recommendation to use an appropriate tool. But just for the fun of sed:

sed  "/tabToChange/{N;s/\(tabToChange>\n<enabled>\)false\(<\/enabled>\)/\1true\2/;}" alpha.txt
  • be careful with the < and >
  • keep the \n in mind you get when appending N
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
0

You can do that with the following commands.

cat alpha.xml | tr '\n' '\f' | sed -e '0,/<tab>\f<enabled>false<\/enabled>\f<\/tab>\f<tabToChange>\f<enabled>false<\/enabled>\f<\/tabToChange >/s//<tab>\f<enabled>false<\/enabled>\f<\/tab>\f<tabToChange>\f<enabled>true<\/enabled>\f<\/tabToChange >/'  | tr '\f' '\n' > alpha1.xml
cp alpha1.xml alpha.xml
rm alpha1.xml

Make that you respect space before any line your want to replace. That is if we have

<tab>
    <enabled>false</enabled>
</tab>
<tabToChange>
    <enabled>false</enabled>
</tabToChange >

That we want to replace with

<tab>
    <enabled>false</enabled>
</tab>
<tabToChange>
    <enabled>true</enabled>
</tabToChange >

The commands to use are:

cat alpha.xml | tr '\n' '\f' | sed -e '0,/<tab>\f    <enabled>false<\/enabled>\f<\/tab>\f<tabToChange>\f    <enabled>false<\/enabled>\f<\/tabToChange >/s//<tab>\f    <enabled>false<\/enabled>\f<\/tab>\f<tabToChange>\f    <enabled>true<\/enabled>\f<\/tabToChange >/'  | tr '\f' '\n' > alpha1.xml
cp alpha1.xml alpha.xml
rm alpha1.xml

Notice that we respect the 4 tabs that come before the <enabled>false</enabled>.

berrytchaks
  • 839
  • 10
  • 18