次のデータ形式のXMLファイルがあります。
<net NetName="abc" attr1="123" attr2="234" attr3="345".../>
<net NetName="cde" attr1="456" attr2="567" attr3="678".../>
....
awkワンライナーを使用してXMLファイルをデータマイニングする方法を教えてもらえますか?たとえば、abcのattr3を知りたいです。それは私に345を返します。
私は、 XML :: LibXMLxml_grep2
に基づいて、libxml2へのperlインターフェースであると呼ばれるツールを作成しました。
これを行うことで、探している価値を見つけることができます。
xml_grep2 -t '//net[@NetName="abc"]/@attr3' to_grep.xml
一般的に、あなたはしません。XML / HTMLの解析は、簡潔に実行しようとしない限り十分に困難です。XMLの限られたサブセットで成功するソリューションを一緒にハックできるかもしれませんが、最終的には機能しなくなります。
その上、すでに書かれた素晴らしいXMLパーサーを備えた素晴らしい言語がたくさんあるので、それらの1つを使用して、あなたの生活を楽にしてみませんか?
awk用に構築されたXMLパーサーがあるかどうかはわかりませんが、awkでXMLを解析する場合は、「ハンマーは釘用、ドライバーはネジ用」というメッセージがたくさん表示されるのではないかと心配しています。答えます。確かにそれは可能ですが、XML :: Simple(私の個人的なお気に入り)または他のXML解析モジュールを使用するPerlで簡単に何かを書く方がおそらく簡単でしょう。
完全を期すために、スニペットがファイル全体の例である場合、それは有効なXMLではないことに注意してください。有効なXMLには、次のように開始タグと終了タグが必要です。
<netlist>
<net NetName="abc" attr1="123" attr2="234" attr3="345".../>
<net NetName="cde" attr1="456" attr2="567" attr3="678".../>
....
</netlist>
無効なXMLにはその用途があると確信していますが、一部のXMLパーサーはそれについて不平を言う可能性があるため、awkワンライナーを使用して「XML」を半ば「解析」しようとすることに完全に取り掛かっていない限り、 XMLを有効にすることを検討します。
あなたの編集に応えて、私はまだワンライナーとしてそれをしませんが、あなたが使うことができるPerlスクリプトはここにあります:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
sub usage {
die "Usage: $0 [NetName] ([attr])\n";
}
my $file = XMLin("file.xml", KeyAttr => { net => 'NetName' });
usage() if @ARGV == 0;
exists $file->{net}{$ARGV[0]}
or die "$ARGV[0] does not exist.\n";
if(@ARGV == 2) {
exists $file->{net}{$ARGV[0]}{$ARGV[1]}
or die "NetName $ARGV[0] does not have attribute $ARGV[1].\n";
print "$file->{net}{$ARGV[0]}{$ARGV[1]}.\n";
} elsif(@ARGV == 1) {
print "$ARGV[0]:\n";
print " $_ = $file->{net}{$ARGV[0]}{$_}\n"
for keys %{ $file->{net}{$ARGV[0]} };
} else {
usage();
}
このスクリプトは、1つまたは2つの引数を使用してコマンドラインから実行します。最初の引数は'NetName'
検索する属性であり、2番目の引数は検索する属性です。属性が指定されていない場合は、そのすべての属性をリストする必要があります'NetName'
。
xmlgawk は XML を非常に簡単に使用できます。
$ xgawk -lxml 'XMLATTR["NetName"]=="abc"{print XMLATTR["attr3"]}' test.xml
この 1 つのライナーで XML を解析し、「345」を出力できます。
If you do not have xmlgawk and your XML format is fixed, normal awk can do.
$ nawk -F '[ ="]+' '/abc/{for(i=1;i<=NF;i++){if($i=="attr3"){print $(i+1)}}}' test.xml
This script can return "345". But I think it is very dangerous because normal awk can not use XML.
この気の利いた小さなスクリプトを試すことができます: http://awk.info/?doc/tools/xmlparse.html