2011-09-16 44 views
1

我試圖去除位於標籤< KEYS>和</KEYS>之間的XML文件中的所有行。perl單線程抓取xml文件中的所有「鍵」

截至我已經得到了一個正則表達式,將在文件中鍵的第一塊匹配,但它不會繼續在文件中匹配其他塊的問題第一遍。我已經嘗試添加「/ G」的正則表達式,我已經試過「-0777」,以啜整個文件一次也不招有什麼差別。下面是Perl的一個班輪:

perl -00 -ne 'print $1 if /(\s+\<KEYS\>\n\s+.*?\n\s+\<\/KEYS\>)/s' someFile.xml 

,我得到這樣的輸出:

<KEYS> 
    <KEY name="cone_id" type="long" nativeType="number(17)"/> 
    <KEY name="bar_id" type="long" nativeType="number(32)"/> 
    <KEY name="foo_type" type="int" nativeType="number(3)"/> 
    </KEYS> 

如上所述有很多文件中的多個塊(這是近五千名線長),但Perl代碼不與任何剩下的搞亂。

有什麼建議嗎?

+3

使用XML解析器::; –

+1

是的,我想有人會建議,但我根本不關心xml結構。我只是剝離出剛好是xml的文本塊。如果這是簡單的舊英語,而且標籤只是單詞,我會遇到同樣的問題。這個問題在整個事件中引發了另一個循環,所以它只是在整個文件中重複正則表達式。 –

回答

7

你的一行會做你想做的通過使兩個變化:

  1. 變化ifwhile
  2. g選項添加到您的正則表達式:/.../gs

或者,它看起來像感興趣的起始和結束標記是在不同的行,由自己。如果是這樣,flip-flop operator可以得心應手:

perl -ne 'print if m{<KEYS>} .. m{</KEYS>}' DATA_FILE 
+0

謝謝,這是做的伎倆。這就是觸發器操作員的提示 –

+1

喜歡觸發器! –

0

你有使用Perl的?如果沒有,請嘗試sed:

sed -i".backup" 's/<KEYS>([^<]*)<\/KEYS>/\1/g' somefile.xml 
5

我不完全確定你的意思是「剝去所有線條」。如果你想打印所有的鍵元素和沒有別人,那麼在這裏你去:

perl -MXML::Simple -e 'print XMLout((XMLin(join "", <>))->{KEYS})' data.xml  

或:

use XML::Simple; 
my $xml = XMLin(join '', <DATA>); 
print XMLout($xml->{KEYS}); 

__DATA__ 
<root> 
    <KEYS> 
    <KEY name="cone_id" type="long" nativeType="number(17)"/> 
    <KEY name="bar_id" type="long" nativeType="number(32)"/> 
    <KEY name="foo_type" type="int" nativeType="number(3)"/> 
    </KEYS> 
    <NOTKEYS1> 
    <KEY name="cone_id" type="long" nativeType="number(17)"/> 
    <KEY name="bar_id" type="long" nativeType="number(32)"/> 
    <KEY name="foo_type" type="int" nativeType="number(3)"/> 
    </NOTKEYS1> 
    <NOTKEYS2> 
    <KEY name="cone_id" type="long" nativeType="number(17)"/> 
    <KEY name="bar_id" type="long" nativeType="number(32)"/> 
    <KEY name="foo_type" type="int" nativeType="number(3)"/> 
    </NOTKEYS2> 
    <KEYS> 
    <KEY name="cone_id" type="long" nativeType="number(17)"/> 
    <KEY name="bar_id" type="long" nativeType="number(32)"/> 
    <KEY name="foo_type" type="int" nativeType="number(3)"/> 
    </KEYS> 
</root> 

即使你不關心結構可言,這是一個有點容易推理比正則表達式,不是嗎?

在任何情況下,這裏有一個正則表達式版本:

perl -e '$a = join "", <>; print $a =~ m/(\s+\<KEYS\>\n\s+.*?\n\s+\<\/KEYS\>)/sg' data.xml 
+0

是的,這就是我的意思,對不起,我沒有更清楚 –

0
perl -MXML::LibXML -e' 
    my $doc = XML::LibXML->new->parse_file($ARGV[0]); 
    $_->parentNode->removeChild($_) 
     for $doc->documentElement->findnodes("//KEYS"); 
    $doc->toFile($ARGV[1], 0); 
' infile outfile 

我加換行以提高可讀性。如果你真的一個真實的內襯可能會刪除它們,但它的工作原理與換行了。

4

如果精心形成的XML,您可以使用xml_grep,附帶XML::Twig,或xml_grep2,在App::xml_grep2

xml_grep -v KEYS to_strip.xml 
xml_grep2 -v '//KEYS' to_strip.xml 

第一種是基於XML ::嫩枝和工作流模式,第二個是基於XML :: LibXML,並在開始grep之前將整個文檔加載到內存中,但它應該更快(我沒有對其進行基準測試)。

這些都不是一個Perl一個襯墊,但他們都用Perl編寫的,所以我希望這是你可以接受的; - )

+0

儘管不是我想到的,但我非常欣賞XML :: Twig和App :: sml_grep2的鏈接。他們看起來非常方便。 –