条件に基づいてxmlファイルからテキストブロックを抽出する

条件に基づいてxmlファイルからテキストブロックを抽出する

fqdns次のファイルからコンテンツを抽出したいが、device場所によってのみ可能です。statusnew

<device id='10.72.48.215'>
    <address>10.72.48.215</address>
    <status>old</status>
    <fqdns>10.72.48.215</fqdns>
    <parent></parent>
    <type>Unknown</type>
    <ports>
    </ports>
    <operatingsystems>
    </operatingsystems>
</device>
<device id='10.72.48.216'>
    <address>10.72.48.216</address>
    <status>new</status>
    <fqdns>10.72.48.216</fqdns>
    <parent></parent>
    <type>Unknown</type>
    <ports>
    </ports>
    <operatingsystems>
    </operatingsystems>
</device>

10.72.48.216だから上記の場合(代わりに)を取得したいと思います10.72.48.215

答え1

XML宣言を追加し、device最上位要素に両方の要素を含める場合は、XPathを使用してファイルを処理できます。

$ cat ./248127.xml
    <device id='10.72.48.215'>
            <address>10.72.48.215</address>
            <status>old</status>
            <fqdns>10.72.48.215</fqdns>
            <parent></parent>
            <type>Unknown</type>
            <ports>
            </ports>
            <operatingsystems>
            </operatingsystems>
    </device>
    <device id='10.72.48.216'>
            <address>10.72.48.216</address>
            <status>new</status>
            <fqdns>10.72.48.216</fqdns>
            <parent></parent>
            <type>Unknown</type>
            <ports>
            </ports>
            <operatingsystems>
            </operatingsystems>
    </device>

$ ( echo '<?xml version="1.0"?><doc>'; cat ./248127.xml ; echo '</doc>' ) \
    | xpath -q -e '//device[status/text()="new"]/fqdns'
<fqdns>10.72.48.216</fqdns>

答え2

複数行検索オプションを持つ pcrgrep コマンドを使用して、これを行うことができます。

pcregrep -M "\<status.*\n.*fqdns\>$"

あなたが要求した説明は次のとおりです。

したがって、-M は複数行を意味します。

\<文字列の先頭の状態。 <の意味を理解するには、\を使用する必要があります。なぜなら、これはシェルにとって特別であるからです。

それから。 (すべての文字)の後に*がある場合は繰り返すことができます。

\n改行

。 *が後に続く文字の場合は繰り返すことができるからです。

その後、文字列fqdns

そして閉じる

\>は>です。もう一度\を使用して意味を表現します。

最後に、$は行の終わりです。

文字列の一致は正規表現と呼ばれます。

https://en.wikipedia.org/wiki/Regular_expression

答え3

シンプルgrep次のようにできます。

grep -A1 "<status>new" sample.xml 
# <status>new</status>
# <fqdns>10.72.48.216</fqdns>

これは、XMLソースが安定していて、行の順序を変更しない場合にのみ推奨されます。 (2番目のブロックに「new」が含まれるように例を修正しました。)

more grep を使用して、次の行をフィルタリングできます。

grep -A1 "<status>new" sample.xml | grep "<fqdns>" 
# <fqdns>10.72.48.216</fqdns>

そしてsed、IPを簡単に抽出できます。

sed -rn '/<status>new/{n; s/.*<fqdns>(.*)<\/fqdns>/\1/p}' sample.xml
# 10.72.48.216

一致<status>newして読んでNアウトラインとS代替タグと閉じるタグの間の<fqdns>セクション。これ-Nsedに「デフォルトで印刷しない」、「-r」を指定すると、マスキングなしで正規表現を作成できます(ここでは.*の周りの括弧)。

関連情報