web-dev-qa-db-ja.com

JSONテキストを解析するsedコマンドを使用した正規表現

私はこのjsonテキストを持っています:

{
    "buildStatus" : {
        "status" : "ERROR",
        "conditions" : [{
                "status" : "OK",
                "metricKey" : "bugs"
            }, {
                "status" : "ERROR",
                "metricKey" : "test_success_density"
            }, {
                "status" : "OK",
                "metricKey" : "vulnerabilities"
            }
        ],
        "periods" : []
    }
}

BuildStatusの全体的なステータス、つまり予想される出力が「ERROR」であったことを抽出したい

"buildStatus" : {
    "status" : "ERROR",
    ....
}

以下のsed式を試しましたが、機能していません。OKを返します。

status= sed -E 's/.*\"buildStatus\":.*\"status\":\"([^\"]*)\",.*/\1/' jsonfile

何が間違っていますか?

15
user1876040

JSONやXMLなどの複雑なネストされたデータ構造を正規表現で解析しないでください。jshonなどの適切なJSONパーサーを使用してください。

最初にインストールする必要があります:

Sudo apt-get install jshon

次に、標準入力を介して解析するJSONデータを提供する必要があるため、別のコマンドの出力をパイプでリダイレクト(|)するか、ファイルをリダイレクト(< filename)できます。

必要なデータを抽出するために必要な引数は次のようになります。

jshon -e "buildStatus" -e "status" -u
  • -e "buildStatus"は、トップレベルのディクショナリから「buildStatus」インデックスを持つ要素を選択します。
  • -e "status"は、上記で選択した第2レベルの辞書から「ステータス」インデックスを持つ要素を選択します。
  • -uは、選択したデータをJSONからプレーンデータに変換します(つまり、ここでは文字列の引用符を削除します)

したがって、実行するコマンドは、データの取得元に応じて、次のいずれかのようになります。

jshon -e "buildStatus" -e "status" -u < YOUR_INPUT_FILE
YOUR_JSON_PRODUCING_COMMAND | jshon -e "buildStatus" -e "status" -u

jshonの詳細については、オンラインでアクセスできるマンページ here を読むか、単にman jshonと入力してください。

16
Byte Commander

jqのジョブ:

jq -r '.["buildStatus"]["status"]' file.json

以下に短縮できます。

jq -r '.buildStatus.status' file.json

-r--raw-output)は、json文字列の書式設定なしで、つまり引用符なしで文字列を出力します。

例:

% cat file.json                   
{
    "buildStatus" : {
        "status" : "ERROR",
        "conditions" : [{
                "status" : "OK",
                "metricKey" : "bugs"
            }, {
                "status" : "ERROR",
                "metricKey" : "test_success_density"
            }, {
                "status" : "OK",
                "metricKey" : "vulnerabilities"
            }
        ],
        "periods" : []
    }
}

% jq -r '.["buildStatus"]["status"]' file.json
ERROR

% jq -r '.buildStatus.status' file.json       
ERROR

まだインストールされていない場合は、インストールしてください(ユニバースリポジトリで利用可能):

Sudo apt-get install jq 
10
heemayl

前述のように、適切なAPIを使用して複雑な構造化データを解析することをお勧めします。 Pythonにはそのためのjsonモジュールがあり、個人的にスクリプトで非常に多く使用しています。必要なフィールドを簡単に抽出できます。

$ python -c 'import sys,json;print json.load(sys.stdin)["buildStatus"]["status"]' <  input.txt
ERROR

ここで起こることは、入力ファイルをpythonのstdinにリダイレクトし、json.load()でそれを読み取ることです。これは、キー「buildStatus」を持つpython辞書になり、「status」キーを持つ別のpython辞書が含まれます。したがって、別の辞書内に保存されている辞書のキーの値を出力しているだけです。かなり簡単です。

単純さは別として、別の利点は、pythonとこのAPIがすべてプリインストールされており、デフォルトでUbuntuに付属していることです。

8

canは実際にsedでこれを行いますが、JSONデータを処理するためのツールを備えた、より洗練された言語を使用することを強くお勧めします。たとえば、Perlやpythonを試すことができます。

さて、あなたの簡単な例では、"status"の最初の出現だけが必要なので、次のようにできます:

$ sed -nE '/status/{s/.*:\s*"(.*)",/\1/p;q}' file.json 
ERROR

トリックは-nを使用して印刷を回避し、行がstatus/status/)に一致する場合、必要な部分以外のすべてを削除しますs/.*:\s*"(.*)",/\1/print行とquit。


個人的には、この同等のgrepコマンドがはるかに簡単であることがわかりました。

$ grep -m1 -oP '"status"\s*:\s*"\K[^"]+' file.json 
ERROR

またはこれ:

$ Perl -ne 'if(s/.*"status"\s*:\s*"([^"]+).*/$1/){print;exit}' file.json 
ERROR

ただし、JSONファイルの解析を計画している場合は、手動でこれを実行しないでください。適切なJSONパーサーを使用します。

6
terdon

言っていないべきsedを使用する(義務的な警告を書かないために誰かが私を投票したと思う)が、nextbuildStatusへの行は、あなた自身の試みで試みているように見えるので、sedに次の行を読むようにNに伝える必要があります。

$ sed -rn '/buildStatus/N;s/.*buildStatus.*\n.*: "(.*)",/\1/p' file
ERROR

ノート:

  • -n要求するまで何も出力しない
  • -r EREを使用(-Eと同じ)
  • /buildStatus/Nこのパターンを見つけて、次の行も読みます
  • s/old/new/oldnewに置き換えます
  • .*行の任意の数の文字
  • \n改行
  • : "(.*)",: "",の間の文字を保存します
  • \1保存されたパターンへの後方参照
  • p作業したパーツを印刷します
4
Zanna

Jsonという別のJsonツール( https://github.com/trentm/json

$ json buildStatus.status < file.json
ERROR

このケーススタディは誤解を招くものです。ツールが機能していないようです。 jsonファイルの変更にjsonを使用することもできます。

$ json -e 'this.buildStatus.status="not error"' < file.json > new.json

あるいは...

$ json -e 'this.buildStatus.status="no errors"' < file.json | json -e 'this.buildStatus.status
no errors

ドキュメンテーション: http://trentm.com/json/


インストールされていない場合:

  • ノードをインストールする
  • およびSudo npm install -g json
0
user216043

sedおよび同様のテキストストリーム処理ツールがJSONやXMLなどの構造化データを解析するのに十分な装備を備えていない理由については、典型的な説明があります。私はそれを手元に持っていませんが、それはそこにあり、おそらく最も少数の状況を除くほとんどすべての状況で必要な表現はすぐに非常に複雑になりますが、構造を解析するために特別に構築された代替ツールはもっと同じ解析でエレガントで読みやすく、効率的です。

murcommentに を入れたように、jqはジョブに適したツールである必要があります。また、同じデータを解析してほとんど成功しないか、負担の大きい成功を収めようと何度か置き換えたのを見て、個人的に非常に興奮していることを保証できます。さらに、出力をフォーマットしたり、その他の方法で制御したりするための多くの機能が含まれています。私が現在忘れている理由またはそれ以上の理由で、jsontoolよりも好きです。

Byte Commander別の回答jshonを推奨しているようです。私はそのツールを使用していませんが、xmlstarletとその構文を思い出させ、出力用にカスタマイズ可能なプレゼンテーションも提供します。

0
Pysis