使用bash脚本添加/删除xml标记

使用bash脚本添加/删除xml标记,xml,bash,scripting,Xml,Bash,Scripting,我有一个要使用bash脚本配置的xml文件。例如,如果我有以下xml: <a> <b> <bb> <yyy> Bla </yyy> </bb> </b> <c> <cc> Something </cc> </c> <d>

我有一个要使用bash脚本配置的xml文件。例如,如果我有以下xml:

<a>

  <b>
    <bb>
        <yyy>
            Bla 
        </yyy>
    </bb>
  </b>

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>

布拉
某物
布拉
(机密信息已删除)

我想编写一个bash脚本,删除部分
(或对其进行注释),但保留xml的其余部分。整个脚本编写过程我都是新手。我想知道是否有人能给我一个关于我应该调查什么的提示

我认为sed可以使用,除非sed是一个行编辑器。我认为删除
标记很容易,但是我不确定sed是否能够删除
标记之间的所有文本


我还需要写一个脚本来添加回删除的部分

如果您想要XML数据的
sed
的最合适替代品,它应该是XSLT处理器。与sed类似,sed是一种复杂的语言,但专门用于XML到任何东西的转换


另一方面,这确实是我要认真考虑切换到真正的编程语言的一个点,比如Python。

< P>可以使用XSLT,例如,这是一个修改的身份转换。默认情况下,它复制所有内容,并为
b
提供一个空模板,该模板不做任何操作(有效地从输出中删除):

它产生以下输出:

<?xml version="1.0" encoding="UTF-16"?><a><!--<b><bb><yyy>
            Bla
        </yyy></bb></b>--><c><cc>
      Something
    </cc></c><d>
    bla
  </d></a>

某物
布拉

这在sed中并不困难,因为sed也适用于范围

尝试以下操作(假设xml位于名为foo.xml的文件中):

sed-i'//,//d'foo.xml
-我会将更改写入原始文件(使用-i.bak保留原始文件的备份副本)

此sed命令将对范围指定的所有行执行操作d(删除)

# all of the lines between a line that matches <b>
# and the next line that matches <\/b>, inclusive
/<b>/,/<\/b>/
#匹配的行之间的所有行
#和下一行匹配,包括
//,//
因此,在简单的英语中,此命令将删除包含行with和行with之间的所有行

如果您希望注释掉这些行,请尝试以下方法之一:

# block comment
sed -i 's/<b>/<!-- <b>/; s/<\/b>/<\/b> -->/' foo.xml

# comment out every line in the range
sed -i '/<b>/,/<\/b>/s/.*/<!-- & -->/' foo.xml
#阻止注释
sed-i's//'foo.xml
#注释掉范围内的每一行
sed-i'//,//s/*//'foo.xml

@OP,您可以使用awk eg

$ cat file
<a>                              

some text before   <b>
    <bb>
        <yyy>
            Bla
        </yyy>
    </bb>
  </b> some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>

$ awk 'BEGIN{RS="</b>"}/<b>/{gsub(/<b>.*/,"")}1' file
<a>

some text before
 some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>
$cat文件
之前的一些文本
布拉
后面有一些文字
某物
布拉
$awk'开始{RS=”“}/{gsub(/.*/,“”)}1'文件
之前的一些文本
后面有一些文字
某物
布拉
使用xmlstarlet:

#xmlstarlet ed -d "/a/b" file.xml > tmp.xml
xmlstarlet ed -d "//b" file.xml > tmp.xml
mv tmp.xml file.xml
sed-i'//,//d'foo.xml
如果b标记也定义了一个值,那么这是否有效
在about HTML中,b标记以

开头,我不得不建议不要使用bash/sed/awk/等。对于这类事情,我建议使用Python、Ruby或Perl。如果在同一行的前面
没有重要内容,在同一行的后面
没有重要内容,那么b标记就起作用了,也就是说,一般不适用于XML,但可能适用于询问者的特殊情况。如果之前或之后行中有任何重要内容,则块注释(替换为)将起作用。这样做的最大问题是,如果已注释块中已经有注释,xml不喜欢嵌套注释。许多其他情况下,这无法处理,例如,它无法区分CDATA块中的标记和文本。在这项工作中使用支持XML的工具要好得多。谢谢:)它适用于多行标记,但对于唯一行上的标记根本不起作用,例如我的文本在Ubuntu9.x版本上安装xmlstarlet,带有默认存储库。在文档中未找到-L标志。是在ubuntu 10.0.4中吗?考虑到这一点,我觉得XML对于配置文件来说太过苛刻了;)应该正确地执行此操作,并添加一个条件(如果操作成功,则仅重命名原始文件)。为了做得更好,还可以使用
mktemp
生成一个具有保证的非冲突名称的临时文件,这也可以避免与使用常量临时文件名相关的一些安全攻击,这仍然是一个比使用
sed
更好的答案。这是一个问题还是一个答案?
# all of the lines between a line that matches <b>
# and the next line that matches <\/b>, inclusive
/<b>/,/<\/b>/
# block comment
sed -i 's/<b>/<!-- <b>/; s/<\/b>/<\/b> -->/' foo.xml

# comment out every line in the range
sed -i '/<b>/,/<\/b>/s/.*/<!-- & -->/' foo.xml
$ cat file
<a>                              

some text before   <b>
    <bb>
        <yyy>
            Bla
        </yyy>
    </bb>
  </b> some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>

$ awk 'BEGIN{RS="</b>"}/<b>/{gsub(/<b>.*/,"")}1' file
<a>

some text before
 some text after

  <c>
    <cc>
      Something
    </cc>
  </c>

  <d>
    bla
  </d>
</a>
#xmlstarlet ed -d "/a/b" file.xml > tmp.xml
xmlstarlet ed -d "//b" file.xml > tmp.xml
mv tmp.xml file.xml
# edit file inplace
xmlstarlet ed -L -d "//b" file.xml
sed -i '/<b>/,/<\/b>/d' foo.xml