[英]Add/remove xml tags using a bash script
我有一個要使用 bash 腳本配置的 xml 文件。 例如,如果我有這個 xml:
<a>
<b>
<bb>
<yyy>
Bla
</yyy>
</bb>
</b>
<c>
<cc>
Something
</cc>
</c>
<d>
bla
</d>
</a>
(已刪除機密信息)
我想編寫一個 bash 腳本,該腳本將刪除<b>
部分(或對其進行注釋),但保持 xml 的其余部分完整無缺。 我對整個腳本編寫很新。 我想知道是否有人可以給我一個關於我應該調查什么的提示。
我想除了sed 是行編輯器之外,可以使用 sed 。 我認為刪除<b>
標簽很容易,但是我不確定 sed 是否能夠刪除<b>
標簽之間的所有文本。
我還需要編寫一個腳本來添加回已刪除的部分。
這在 sed 中不難做到,因為 sed 也適用於范圍。
試試這個(假設 xml 在一個名為 foo.xml 的文件中):
sed -i '/<b>/,/<\/b>/d' foo.xml
-i 將更改寫入原始文件(使用 -i.bak 保留原始文件的備份副本)
此 sed 命令將對范圍指定的所有行執行操作 d(刪除)
# all of the lines between a line that matches <b>
# and the next line that matches <\/b>, inclusive
/<b>/,/<\/b>/
因此,用簡單的英語,此命令將刪除包含 <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
使用 xmlstarlet:
#xmlstarlet ed -d "/a/b" file.xml > tmp.xml
xmlstarlet ed -d "//b" file.xml > tmp.xml
mv tmp.xml file.xml
您可以使用 XSLT,例如修改后的身份轉換。 它默認復制所有內容,並且有一個空模板b
什么都不做(有效地從輸出中刪除):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--Identity transform copies all items by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Empty template to match on b elements and prevent it from being copied to output -->
<xsl:template match="b"/>
</xsl:stylesheet>
創建一個使用 Java 和 Xalan 命令行實用程序執行轉換的 bash 腳本,如下所示:
java org.apache.xalan.xslt.Process -IN foo.xml -XSL foo.xsl -OUT foo.out
結果是這樣的:
<?xml version="1.0" encoding="UTF-16"?><a><c><cc>
Something
</cc></c><d>
bla
</d></a>
編輯:如果您希望將b
注釋掉,以便更容易放回原處,請使用此樣式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--Identity transform copies all items by default -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Match on b element, wrap in a comment and construct text representing XML structure by applying templates in "comment" mode -->
<xsl:template match="b">
<xsl:comment>
<xsl:apply-templates select="self::*" mode="comment" />
</xsl:comment>
</xsl:template>
<xsl:template match="*" mode="comment">
<xsl:value-of select="'<'"/>
<xsl:value-of select="name()"/>
<xsl:value-of select="'>'"/>
<xsl:apply-templates select="@*|node()" mode="comment" />
<xsl:value-of select="'</'"/>
<xsl:value-of select="name()"/>
<xsl:value-of select="'>'"/>
</xsl:template>
<xsl:template match="text()" mode="comment">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="@*" mode="comment">
<xsl:value-of select="name()"/>
<xsl:text>="</xsl:text>
<xsl:value-of select="."/>
<xsl:text>" </xsl:text>
</xsl:template>
</xsl:stylesheet>
它產生這個輸出:
<?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
替代品來處理 XML 數據,那么它應該是 XSLT 處理器。 與sed
一樣,它是一種復雜的語言,但專門用於將 XML 轉換為任何內容的任務。
在另一方面,這似乎是在我會認真考慮切換到一個真正的編程語言,像Python點。
@OP,您可以使用 awk 例如
$ 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>
# edit file inplace
xmlstarlet ed -L -d "//b" file.xml
sed -i '/<b>/,/<\/b>/d' foo.xml
如果 b 標簽在 HTML 中也定義了一個值,那么這是否有效,b 標簽以<b id="Test Step">
開頭
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.