2012-02-08 6 views
9

私は特定のプロパティを持つxmlファイルを探しています。たとえば、次のパターンが含まれるファイル:そのようなファイルについてはunixコマンドラインから基本的なxml解析を行う最も簡単な方法

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

は、私のような、別のタグの値を解析したいと思います:

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

に沿ってファイル名をプリントアウト"asdf"と入力します。コマンドラインからこれを達成する最も簡単な方法は何ですか?

私が考えていたアプローチの1つは、-lオプションを指定してgrepを使用して一致するファイルをフィルタリングし、次にxargs grepを使用してロールの値を抽出することでした。しかし、grepは複数行正規表現ではうまく動作しません。私はそれが-Pzoオプションを使って行うことができることを示した別の質問を見ましたが、私の場合はうまく動かない運がありませんでした。より簡単なアプローチはありますか?

+0

あなたはPerlなどのスクリプト言語を使用したくない特別な理由がありますか? – Tom

+0

いいえ、perlの解決策は素晴らしい、できればコンパクトな1ライナーですが、私はそれを書く最善の方法を知らない。 – jonderry

+0

xmlstarlet、xpath、およびperlのxpathモ​​ジュールは、私が検索を実行するシステムにはインストールされていませんが、もっとも基本的なツールだけで動作するソリューションがあれば役に立ちます。 – jonderry

答えて

2

私にとって最も簡単なのは、コマンドラインからSaxonを使用することです。

ここではXPath on the command lineを使用した例です。これはシェルスクリプトと組み合わさって、あなたが求めているものとまったく同じです。

+0

これは最もポータブルなソリューションです。必要。 –

0

あなたの問題をより慎重に処理したいと考えていましたが、時間がなくなりました。申し訳ありません。

とにかく - perlにはxmlを読むためのいくつかの非常に良いモジュールがあります。

特に、次の記事、perl and xml on the command lineがおそらく興味深いでしょう。

0

私は通常、PerlのXML::XSH2を使用します。対話的にXMLファイルを処理したり、スクリプトを作成することができます。このスクリプトは、(未テスト)のようになります。

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

次のLinuxコマンドは、指定された値にアクセスするためのXPathを使用してXMLファイル内

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

XMLファイルを一致させるための出力例:

./test1.xml asdf 
./test4.xml 1234 
1

私は基本的なperl/awk機能(基本的にはタグの貧しい人の解析)を使っていくつかの解決策を試しました。基本的なperl/awk機能だけを使って改善が見られる場合は、私に教えてください。私は、特定のタグを参照してフラグを設定することによって、複数行の正規表現を扱うことを避けました。不器用なのですが、うまくいきます。

の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、なぜあなたがdownvotedを説明してください。 – 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> 
関連する問題