2014-03-31 47 views
0

我需要搜索一個包含數百或數千個文件的目錄,每個文件包含具有特定字符串的一個或多個實例(包含數據的開始/結束標記)的XML。 我可以通過做Unix - 同一行上的文件名和字符串結果

grep -ho '<mytagname>..............<\/mytagname>' /home/xyzzy/mydata/*.XML > /home/mydata/tagvalues.txt 

然後幾個sed命令脫光標籤獲取字符串的所有實例,所以我風與僅僅包含值的列表中的文件:

value001 
    value002 
    value003 

(etc)

理想情況下,我想讓文件的每一行都包含文件名,以便我可以導入數據庫進行分析。

所以我的結果會是這樣的

fileAAA value001 
fileAAA value002 
fileAAA value003 
fileBBB value004 

上面的格式非常靈活 - 可以有空格或其他分隔符,它甚至還包括了開始/結束標記。

我已經能夠獲得最接近的是使用grep -o

fileAAA:value001 
value002 
value003 
fileBBB:value004 

一個Perl的一個班輪似乎理想,但我是新足的是,我不知道如何開始。

回答

0

awk怎麼樣?

awk -F'</?mytagname>' '$2 {print FILENAME,$2}' /home/xyzzy/mydata/*.XML 

說明:

  • -F regex - 組字段分隔符必須從而包圍在它自己的引號中的單獨的參數
  • $2 - 如果第二字段具有值
  • {print FILENAME,$2} - 打印文件名空間第二個字段的值
+0

感謝 - 這兩個的(perl的和awk)在某種程度上工作:它們似乎只是在文件中第一次出現字符串。當我使用我的原始grep時,我得到了成千上萬的點擊(即使我排序並採取唯一值)。當我使用其中的任何一個命令時,我得到大約7500個命中,這是目錄中的文件數。 – JOATMON

+0

啊哈 - 做了一點挖掘,並找到了答案在另一個帖子[這裏](http://stackoverflow.com/questions/19031552/perl-one-liner-to-match-all-occurrences-of-regex) - 所以我將perl命令改爲while(/ (。*?)<\/mytagname>/g)'而不是if,這給了我一個更可信的數字。 – JOATMON

4

Cou LD用一個班輪像這樣做:

perl -lne 'print "$ARGV $1" if /<mytagname>(.*?)<\/mytagname>/' *.xml 

不過,我強烈建議你使用一個實際的XML解析器像XML::TwigXML::LibXML

use strict; 
use warnings; 

use XML::LibXML; 

for my $file (</home/xyzzy/mydata/*.XML>) { 
    my $doc = XML::LibXML->load_xml(location => $file); 
    for my $node ($doc->findnodes("//mytagname")) { 
     print "$file " . $node->textContent() . "\n"; 
    } 
} 
相關問題