2017-08-09 173 views
-1

我有兩個XML文件,我想複製和粘貼與SED

  1. 文件中查找特定的XML節點A
  2. 複製
  3. 找到一個特定的部分中的文件B文件B
  4. 粘貼複製的節點。

sed中已被使用在我的機器上,但我在尋找合適的正則表達式配置的麻煩。

實施例用於文件A:

<Containers> 
    <Container id="1"> <-- to be copied start 
    blubb 
    </Container> <-- to be copied end 
    <Container id="2">blobb</Container> 
</Containers> 

實施例用於文件B:

<Containers> 
    <Container id="1"> <-- copied here start 
    blubb 
    </Container> <-- copied here end 
    <Container id="99">blibb</Container> 
</Containers> 

我做的:

<Containers> 
    <Container id="99">blibb</Container> 
</Containers> 

通過從<Container id="1"切割成</Container>以獲得所需的輸出文件B實施例知道它會更乾淨,也許更容易使用XML解析器和其他工具,但我需要使用sed,我不是一個非常有經驗的sed/regex用戶。我只是打得四處「替代」和「刪除」一點點,但僅此而已......

我願澄清:

  • 我需要使用sed的,因爲這是唯一的工具可用在機器上。
  • 我知道,我能做到這一點在其他編程語言和其他工具,但在這裏,這是不可能的。應該運行的機器不在我的控制之下!

我知道我不應該使用正則表達式的XML/XHTML - 我知道,但地球是複雜得多。

我cygwin的版本運行此。

更新1:

幾個反應。由於這似乎是不可能找到與SED的解決方案。 感謝所有了解這個問題,並試圖幫助!

如果有人仍然可以看到一個潛在的解決方案,那麼請讓我知道。但挑戰在於使用sed。我已經使用XML解析器與提升,QT,C#,Java的,......但是,這裏根本就不是問題,如果我可以選擇......我不能。

更新2:

謝謝大家,特別是本傑明W.這是絕對有可能使用SED來解決這個問題,而是多次表示,如果你必須使用一個XML解析lib和另一可能性技術,那麼這應該是一條路。

對我來說,一個非技術問題(僞安全指南)已經解決了與現有的技術解決方案。

這是我的最終解決方案:

sed "/<Container id=\"1\">/,/<\/Container>/!d" fileA.xml |^
sed -i "/<Containers>/r /dev/stdin" fileB.xml 

謝謝。

+0

Ruby,Perl,Python,Swift,都有簡單的xml解析器。不要嘗試使用面向行的1980年代ERE正則表達式工具來解析面向塊的語法。 Square peg =>圓孔。不要使用錘子。 – dawg

+0

*我不是一個非常有經驗的sed/regex用戶*這是一種不好的方法來嘗試和學習... – dawg

+0

我認爲你錯過了一點 - 使用Regex解析任意XML比「更困難」更糟糕,這實際上在邏輯上是不可能的。如果您不能使用XML解析器,那麼您無法執行該項目。 – EJoshuaS

回答

5

這是一個sed命令,可以完成示例要求的操作。讓我先介紹它,然後列出將如何突破:產生

<Containers> 
    <Container id="1"> 
    blubb 
    </Container> 
    <Container id="99">blibb</Container> 
</Containers> 

這需要GNU的sed從特殊文件/dev/stdin讀取標準輸入

sed '/<Container id="1">/,/<\/Container>/!d' fileA.xml | 
    sed '/<Containers>/r /dev/stdin' fileB.xml 

;沒有GNU sed,第一個命令的輸出可以保存到臨時文件中,然後從那裏讀取。

第一條命令查找以匹配<Container id="1">並以匹配<\/Container>匹配的行結尾的行開始。該範圍外的所有外部被刪除。

第二個命令查找匹配<Containers>的行,然後插入第一個命令的輸出與r

下面是如何能突破:

  • 空白中的任何變化(<Container id="1">和它打破)
  • 在換行符
    • 在同一行打開標籤關閉標籤的任何差異:在休息
    • <Containers>不上自己的一條線:在休息
    • 下一個節點上的同一行開始爲關閉標籤</Container>:休息
  • ID爲1
  • 任何其他<Containers>節點其他地方的任何<Container>子節點fileB.xml
  • 用相同的節點名稱

...等等任何嵌套。

正如在評論中指出的那樣,這應該是最後一招。或許你最好把你的輸入文件複製到一臺擁有適當工具的機器上,然後將它們複製回來,而不是使用它。