次のXMLファイルがあります。
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter><Record>2</Record></FileFooter>
レコードタグの値を抽出したい。以下のようにsedコマンドを使用しますが、出力は提供されません。
sed -n '/Record/{s/.*<Record>//;s/<\/Record.*//;p;}' filename
これに助けが必要ですか?
ベストアンサー1
FileFooter/Record
ノードの値をスクリプトのシェル変数に入れる最も簡単な方法はxmlstarlet
。
以下は、XML文書がうまく構成されていると仮定していますが、サンプル文書には複数のルートタグがあるためではありません(最も興味深いと思うビットを抽出したため)。また、ノードが1つしかないとしますFileFooter/Record
。それ以外の場合は、値を繰り返す必要があります。
value=$( xmlstarlet sel -t -v '//FileFooter/Record' file.xml )
式は、//FileFooter/Record
私たちが興味のあるノードのXPathです(実際には各 FileFooter/Record
文書全体のノード)。を通じてsel -t -v
特定またはXPath()を一致させて得られた値を抽出したいと伝えますxmlstarlet
。-v
sel -t
問題のデータにルートタグがないため、次のコマンドを実行して欠落しているタグを動的に挿入し、修正された文書を解析し、シェル変数から必要な値を抽出できますvalue
。
value=$(
{ echo '<root>'; cat file.xml; echo '</root>'; } |
xmlstarlet sel -t -v '//FileFooter/Record'
)
欠落している単一のルートノードが呼び出されると仮定すると、次のものもroot
使用できます。xq
https://kislyuk.github.io/yq/)、JSONパーサーの周りに構築されたXMLパーサーレイヤーですjq
。
value=$( xq -r '.root.FileFooter.Record' file.xml )
.[].FileFooter.Record
ルートノードの名前を入力したくない場合は、この方法を使用できます(FileFooter
ただし、まだルートノードのすぐ下にあるノードであると仮定します)。
このコマンドはXMLファイルをJSONに変換します。 XML文書が次の場合:
<?xml version="1.0"?>
<root>
<FileHeader>SampleFile</FileHeader>
<Name>aaaa</Name>
<Place>bufnkf</Place>
<Name> bjfbhj</Name>
<Place>bvdhbf</Place>
<FileFooter>
<Record>2</Record>
</FileFooter>
</root>
ユーティリティxq
はそれを次のJSONドキュメントに変換します。
{
"root": {
"FileHeader": "SampleFile",
"Name": [
"aaaa",
"bjfbhj"
],
"Place": [
"bufnkf",
"bvdhbf"
],
"FileFooter": {
"Record": "2"
}
}
}
xq
次に、jq
式を使用して呼び出して.root.FileFooter.Record
値を抽出します。