2012-02-08 23 views
9

Belirli özelliklere sahip xml dosyalarını arıyorum. Örneğin, aşağıdaki kalıbı içeren dosyalar:Unix komut satırından temel xml ayrıştırma işlemini yapmanın en kolay yolu

<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 

Ve boyunca dosya adı çıktısını: Bu tür dosyalar için

<param-value> 
    <name>Hosts</name> 
    <description>some description</description> 
    <value></value> 
</param-value> 

, ben gibi, başka bir etiket değerini ayrıştırmak istiyorum "asdf" ile. Bunu komut satırından yapmanın en kolay yolu nedir? Sadece eşleşen dosyaları filtrelemek için -l seçeneği ile grep kullanarak ve sonra xargs kullanıyordum düşünüyordum

Bir yaklaşım Rolleri değerini ayıklamak için grep. Ancak, grep çok satırlı regex'lerle iyi çalışmaz. -Pzo seçenekleriyle yapılabileceğini gösteren başka bir soru gördüm, fakat davamda çalışmak için hiç şans yoktu. Daha basit bir yaklaşım var mı? Benim için

+0

Böyle perl gibi bir kodlama dili kullanmak istemediğiniz belirli bir nedeni var mı? – Tom

+0

Hayır, bir perl çözümü harika, tercihen kompakt bir tek liner olurdu, ancak yazmanın en iyi yolunu bilmiyorum. – jonderry

+0

Sadece en temel araçlarla çalışan bir çözüm bulmak yararlı olacaktır, xmlstarlet, xpath ve perl'in xpath modülü, arama yapacağım sistemde yüklü değil. – jonderry

cevap

2

en basit komut satırından Saxon kullanmaktır.

İşte XPath on the command line kullanarak bir örnek. Bu, bir kabuk senaryosuyla birleşince, tam olarak ne istediğini yapardı.

+0

Bu en taşınabilir çözüm gibi görünüyor ne ben gerekir. –

0

Sorununuzu daha dikkatli çalışmayı ummuştum, ama zamanım tükendi, üzgünüm.

Neyse - perl xml okumak için bazı çok iyi modülden oluşmaktadır. Özellikle

, aşağıdaki makale, perl and xml on the command line, muhtemelen ilgi çekmektedir.

0

Genellikle Perl'in XML::XSH2 kullanın. XML dosyalarını etkileşimli olarak işleyebilir veya komut dosyası olarak kullanabilirsiniz.

for my $file in { glob "*.xml" } { 
    open $file ; 
    my $param_value = //param-value[name="Hosts"] ; 
    if $param_value echo $file $value/value ; 
} 
12

aşağıdaki linux komut XML dosyalarını eşleştirmek için XML dosyası

for xml in `find . -name "*.xml"` 
do 
echo $xml `xmllint --xpath "/param-value/value/text()" $xml`| awk 'NF>1' 
done 

Örnek çıktı dahilinde belirtilen değerlere erişmek için XPath kullanır:

./test1.xml asdf 
./test4.xml 1234 
komut dosyası (denenmemiş) gibi bir şey olurdu
1

Temel perl/awk işlevlerini (temel olarak fakir bir erkeğin etiketleri ayrıştırması) kullanarak birkaç çözüm hazırladım. Sadece temel perl/awk işlevlerini kullanarak herhangi bir gelişme görürseniz, bana bildirin. Belirli bir etiketi gördüğümde bir bayrak ayarlayarak çok satırlı normal ifadelerle uğraşmaktan kaçındım. Biraz sakar ama işe yarıyor.

perl:

perl -ne '$h = 1 if m/Host/; $r = 1 if m/Role/; if ($h && m/<value>/) { $h = 0; print "hosts: ", $_ =~ /<value>(.*)</, "\n"}; if ($r && m/<value>/) { $r = 0; print "\nrole: ", $_ =~ /<value>(.*)</, "\n" }' 

awk:

awk '/Host/ {h = 1} /Role/ {r = 1} h && /<value>/ {h = 0; match($0, "<value>(.*)<", a); print "hosts: " a[1]} r && /<value>/ {r = 0; match($0, "<value>(.*)<", a); print "\nrole: " a[1]}' 
+4

Downvote, lütfen neden reddedildiğinizi açıklayın. – jonderry

1
$ xmlstarlet ed -u /param-value/name -v Roles -u /param-value/value -v asdf data.xml 

<?xml version="1.0"?> 
<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 
İlgili konular