GNU/Linux >> Linux の 問題 >  >> Linux

Linux で XPATH の例を使用して XML を解析し、タグを削除する方法 (Linux で PIPE を使用して複数のコマンドを組み合わせる方法)

このチュートリアルでは、便利なマルチパート コマンドを 1 つずつ作成するプロセスについて説明します。

ターミナルで複雑なコマンドを作成するには、パイプを理解する必要があります。パイピングとは、基本的に、あるコマンドの出力を受け取り、それを別のコマンドに入力として送信することです。これは | で行われます。 (パイプ) 記号。

先月、小規模なプロジェクトで、同様の XML ファイルを繰り返し読み取って、別のプログラムにテスト データを提供する必要がありました。ダウンロード、保存、解析、および繰り返しを行うのは煩わしいほど頻繁に行う必要があります。基本的な要件は次のとおりです。

<オール>
  • URL から XML を取得
  • XML を解析し、すべての要素の 2 つの属性のみを選択します
  • コンテンツのみが残るようにタグを削除
  • 標準出力に送信
  • 1.コマンドラインが XML を解析できることを証明する

    昨年、Ruby ライブラリの REXML::Xpath をスクリプトに使用しましたが、コマンド ラインで利用できる Perl バージョンがあったことを思い出しました。 CPAN でインストールできます:

    $ cpan XML::XPath

    サンプルの従業員ファイルを使用して、アイデアを試してみましょう。この employees.xml ファイルをブラウザで開き、それをブラウザで開き、employees.xml として保存します。

    これで、xpath コマンドと再生するファイルができました。

    簡単なパスでテストします:

    $ xpath employees.xml '/DIRECTORY/EMPLOYEE/FIRST_NAME'
    ­­ NODE ­­
    <FIRST_NAME>Steven</FIRST_NAME>­­ NODE ­­
    <FIRST_NAME>Susan</FIRST_NAME>­­ NODE ­­
    <FIRST_NAME>Marigold</FIRST_NAME>­­ NODE ­­
    ...
    <FIRST_NAME>Sunny</FIRST_NAME>­­ NODE ­­
    <FIRST_NAME>Flo</FIRST_NAME>

    優秀な!選択したパスの各 /EMPLOYEE の FIRST_NAME 属性を出力します。しかし、複数の XPath 要素を選択するにはどうすればよいでしょうか。 XPath 構文を見ると、方法がわかります。 XPath 式を | と組み合わせるOR 式を作成します。

    $ xpath employees.xml '/DIRECTORY/EMPLOYEE/ FIRST_NAME | /DIRECTORY/EMPLOYEE/LAST_NAME'
    --­­ NODE ­­--
    <FIRST_NAME>Steven</FIRST_NAME>­­-- NODE ­­--
    <LAST_NAME>Sanguini</LAST_NAME>­--­ NODE ­--­
    <FIRST_NAME>Susan</FIRST_NAME>­­-- NODE ­­--
    <LAST_NAME>Aquilegia</LAST_NAME>--­­ NODE --­­
    ...
    <FIRST_NAME>Flo</FIRST_NAME>­­-- NODE ­­--
    <LAST_NAME>Lobalessia</LAST_NAME>

    お知らせ、こちら |は OR 演算子として解釈され、出力リダイレクトではありません。

    また、このステートメントでは、Y だけでなく X も選択しています。なぜ OR は両方を選択するのでしょうか? XML ドキュメント内の各ノードを個別に評価し、ノードが A または B の場合は評価に合格し、出力に渡されます。

    2. XML をダウンロードして STDOUT に送信

    この次のステップは実際にはコマンド ラインの前の方にあり、個別にビルドします。私は、概念実証として、最初に最も難しい、または「そんなことはできない」コマンド エントリを作成することを好みます。ステップ 1 が機能しない場合、周囲のコマンド ライン作業を行うのは無意味です。

    cURL は、HTTP インタラクションの強力なコマンドです。これらの curl の例は、正しい方向への出発点となります。

    必要に応じてリダイレクトに従って、場所を指定します。これには、次のオプションを使用します:-L ‘https://www.thegeekstuff.com/scripts/employees.xml’

    cURL の情報出力をオフにします。そしてGETプロトコルを指定します。これには、次のオプションを使用します:-s G

    それでは、以前にダウンロードしたファイルの URL でコマンドをテストしてみましょう:

    $ curl -­s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml'
    <?xml version="1.0" encoding="UTF­8"?>
    <DIRECTORY>
    <EMPLOYEE>
    <FIRST_NAME>Steven</FIRST_NAME>
    <LAST_NAME>Sanguini</LAST_NAME>
    <STORE_NUMBER>4</STORE_NUMBER>
    <SHIFT>FIRST</SHIFT>
    <AUM>$2.44</AUM>
    <ID>031599</ID>
    </EMPLOYEE>
    ..

    デフォルトは STDOUT です。ファイル引数を削除して XPath にリダイレクトするので、これは良いことです:

    $ curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | xpath \
    '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID'
    ­--­ NODE ­­--
    <LAST_NAME>Sanguini</LAST_NAME>­­-- NODE ­­--
    <ID>031599</ID>­­ NODE ­­
    <LAST_NAME>Aquilegia</LAST_NAME>­­-- NODE -- ­­
    <ID>030699</ID>­­-- NODE ­­--
    ...
    <LAST_NAME>Lobalessia</LAST_NAME>--­­ NODE --­­
    <ID>022299</ID>

    これにより、期待される出力が生成されます。すごい!理由はわかりませんが、XPath は「NODE」を標準エラー (STDERR) に送信します。しかし、考えられる理由は後でわかります。

    3. XML タグを取り除く

    これらのタグを取り除き、コンテンツだけを取得できるようにする必要があります。 Sed は、オンザフライで正規表現置換を行うための最適なツールです。 REGEX の学習は、この記事の範囲外です。

    詳細については、Python 正規表現に関する一連の記事を参照してください。

    複数の引数とフラグを使用して複雑なコマンドを作成するときは、簡単な例を使用して、それがうまくいくまで作業してから、実際の引数を使用してコンテキストに貼り付けるのが最善だと思います。テスト置換のために単純な文字列を sed にパイプします。 Sed はデフォルトで STDIN で動作します。

    $ echo "This<strong> is </strong>a test." | sed ­-re 's/i//g'
    Ths<strong> s </strong>a test.

    Ok。それはうまくいきます。検索を書き直して、タグを置き換えます。

    $ echo "This<strong> is </strong>a test." | sed ­-re 's/<\w+>//g'
    This is </strong>a test.

    良い。接頭辞「\」でエスケープされた「/」を追加して終了タグを削除し、接尾辞「?」で省略可能にします

    $ echo "This<strong> is </strong>a test." | sed ­re 's/<\/?\w+>//g'
    This is a test.

    完全。まさに私たちが期待していたものです。

    4.すべてをまとめる

    コマンドの個々の部分を作成したので、 | で結合された論理的な順序でそれらを貼り付けます。 .

    curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | \
    xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID ' | \
    sed ­-re 's/<\/?\w+>//g'

    出力:

    Found 72 nodes:
    --­­ NODE -- ­­
    ­--­ NODE ­­--
    ...
    Sanguini031599Aquilegia030699...

    ええとああ!おそらく、これが「 NODE 」マーカーがある理由です。これをファイルにパイプすると、NODE テキストは続きません。それらは標準エラー (STDERR) に送信されますが、`2>&1` (説明) を使用して STDOUT にリダイレクトし、sed 置換 `sed re 's/ NODE //g'` を使用して、タグ。

    curl -­s -­G -­L 'https://www.thegeekstuff.com/scripts/employees.xml' | \
    xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID '
    2>&1| sed -­re 's/­--­NODE--­­//g' | sed -­re 's/<\/?\w+>//g'

    出力:

    Found 72 nodes:
    Sanguini
    031599
    Aquilegia
    030699
    ...
    Lobalessia
    022299

    完全。現在、プロジェクトに取り組んでいるとき、ファイルを保存したり複雑なソフトウェアを実行したりする手間をかけずに、Web 上の XML ファイルからサンプル データを STDOUT にすばやく取得できます。これを `tail –n+3` にパイプして、最初の 2 つの応答行を切り取ることもできます。

    この記事は、パイプを使用して複数のコマンドを組み合わせる方法を学習した場合に実行できるさまざまなことの一例にすぎません。


    Linux
    1. Linuxコマンド-概要と例

    2. dfおよびduコマンドを使用してLinuxのディスク容量を確認する

    3. Linuxのヘッドコマンドとテールコマンドを例で説明

    1. Linuxでパイプと名前付きパイプを使用する方法(例付き)

    2. niceおよびreniceコマンドを使用してLinuxプロセスの優先度を設定する方法

    3. MTR コマンドの例を使用して Linux で Ping と Traceroute を組み合わせる方法

    1. ncおよびpvコマンドを使用して2台のコンピューター間でファイルを転送する方法

    2. Linuxでの例で「cat」および「tac」コマンドを使用する方法

    3. Linuxでシャットダウンおよび再起動コマンドを無効にする方法