次のXMLがあります。
<artifactId>myproject</artifactId>
<version>1.14.0-SNAPSHOT</version>
バージョンを抽出したいです1.14.0-SNAPSHOT
。つまり、2つのgrepとパイプを使用してこれを行う方法を知っています。
$ grep -A1 "<artifactId>myproject</artifactId>" pom.xml | grep -Eo "\d+.\d+.\d+-SNAPSHOT"
2つを1つにまとめるにはどうすればよいですか?これにawkまたはsedを使用する方が良いでしょうか?
答え1
<version>
次の行以降に確実であればmyproject
sed -n '
\|<artifactId>myproject</artifactId>|{
n #get next line
s|[[:blank:]]*</\?version>[[:blank:]]*||gp #remove tags and print
}
' pom.xml
またはあなたが持っているなら正規表現
grep -zoP '<artifactId>myproject</artifactId>\s*\n\s*<version>\K[^<]+' pom.xml
答え2
あなたはコメントで移植可能なものが欲しいと言いました。本当に素晴らしいことですが、そうしないように心からアドバイスします。XML
状況に合った言語ですが、正規表現はそうではありません。正規表現はXML結果を正しく解析しません。
せいぜい、XMLが同じ形式で保持されている場合にのみ機能するハックを取得できます。しかし、XML仕様によれば、形式は偶然であり、同じ意味を維持することができます。これは危険な仮定であり、脆弱なコードを引き起こす可能性があります。
私はあなたがこれをしたい理由があることを知っています。あなたはすでに方法を提供する答えを持っています。私はパーサーがまだ正しい答え。
ただし、XMLパーサーを使用すると、xpath
正規表現に非常に似ていますが、階層的な情報を取得できます。
このような:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parse ( \*DATA );
my $version = $twig -> get_xpath('//item/artifactId[string()="myproject"]/../version',0)->text;
print $version;
__DATA__
<xml>
<item>
<artifactId>myproject</artifactId>
<version>1.14.0-SNAPSHOT</version>
</item>
</xml>
xpath
どのように機能するかを見ることができます。//item
構造内のどこでもアイテムを探します。[string()=
テキストの内容を照会します。[@someAtt="fish"]
プロパティの確認などの操作を実行できます。
次に、..
上に(item
)上がってversion
要素を取得します。次にtext
値を取得します。
個人旅行者として:
perl -MXML::Twig -0777 -e 'print XML::Twig -> parse ( <> ) -> get_xpath('/item/artifactId[string()="myproject"]/../version',0)->text,"\n" yourxmlfile.xml
今はXML::Twig
学習しやすいと思ってお勧めします。XML::LibXML
かなり良いです。
ただし、WindowsではStrawberry Perlと一緒に展開され、多くのパッケージマネージャまたはで簡単に使用できますCPAN
。
または -xmlstarlet
あなたも同じことをすることを許可する必要があります。