2012-10-09 236 views
0

我有下面的XML片斷從我的代碼庫替換節點。我有一個現有的shell腳本來替換上面文件中的一些數據。通過shell腳本

現在,我需要修改我現有的shell腳本評論的部分如下圖所示:

  <!-- entry key="/mycompany/abc"> 
       <value>Mike</value> 
      </entry> 
      <entry key="/mycompany/pqr"> 
       <value>John</value> 
      </entry --> 

是否可以發表評論上述2項通過shell腳本對此有何評論?我可以替換任何發生的事件,因爲我只有一次這樣的獨特事件,但是我無法替換/ mycompany/pqr節點中的結束標記,因爲如果我嘗試用<替換它,所有事件將被替換/ entry - >

關於如何在shell腳本中替換這個關閉節點的想法?

謝謝!

+0

使用XSLT處理器和樣式表。在所有輸出節點的節點上使用模板匹配 - 然後創建第二個模板,以匹配您想要排除的內容,不會發出任何內容。 – mythagel

+0

在shell腳本中的xslt處理器? – Mike

+0

如果你需要一個'純'的shell腳本替代我會看看sed或awk。 – mythagel

回答

0

使用XSLT樣式表是這樣的:

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

<xsl:output omit-xml-declaration="no"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/property/map/entry[@key='/mycompany/abc']"/> 
    <xsl:template match="/property/map/entry[@key='/mycompany/pqr']"/> 
</xsl:stylesheet> 

然後通過shell腳本使用xsltproc的XSL處理器:

$ xsltproc fix.xslt document.xml 

,這將給你:

<?xml version="1.0"?> 
<property name="myData"> 
     <map> 


      <entry key="/mycompany/xyz"> 
       <value>Sara</value> 
      </entry> 
     </map> 
    </property> 

如果您真的需要那些註釋掉的節點,那麼我的xslt-foo不夠強大 - 你可能需要<xsl:comment>

編輯:使用awk A液:

awk '/<entry key="\/mycompany\/(abc|pqr)">/,/<\/entry>/ {p=1}; /.*/{ if(p==0) {print;}; p=0 }' blah.xml 

結果:

<property name="myData"> 
    <map> 
     <entry key="/mycompany/xyz"> 
      <value>Sara</value> 
     </entry> 
    </map> 
</property> 

請注意,awk的版本不會與嵌套標籤正常工作。

-nick

+0

您的awk腳本看起來很酷。如果你能解釋你的awk腳本,特別是標誌p = 1等,我會很感激。 – Mike

+0

當然,第一部分匹配一個以mycompany鍵包含'abc'或'pqr'的入口標籤開始的多行模式。逗號指定這是以關閉條目標記終止的範圍。當該模式匹配時,它將變量'p'設置爲1.第二部分匹配所有字符串並將其打印出來,IFF p爲零(即,如果我們不匹配先前模式,則將其打印出來)。打印完文本後,它將p重置爲零以繼續下一個文本塊。 – mythagel

0

聲明:我想用awk/SED/...爲XML文件作爲一個不好的想法;如果格式更改,標籤之間的行號不同,則最終會生成一個bung XML文件。

BEGIN{ 
     count=-6 
    } 
    { 
     if($0 !~ /\/mycompany\/pqr/ && NR != count+5){ 
      print $0 
      next 
     } 
     if($0 ~ /\/mycompany\/pqr/) { 
     count=NR; 
     print gensub(/(entry)/, "!-- \\1", "1") 
     }else{ 
     print gensub(/(entry)/, "\\1 --", "1") 
     } 
    } 

另存爲 「something.awk」,像下面這樣運行:

awk -f something.awk your_file.xml