シェルから複数のjsonオブジェクトをjson配列にマージする方法

シェルから複数のjsonオブジェクトをjson配列にマージする方法

新しいjsonリストを形成するには、ファイルからjsonデータの特定のフィールドを読み取る必要があります。このファイルは以下によって生成されました。reading data from multiple servers via pssh

# pssh_result.txt
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13",...}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23",...}
...
...

現時点ではフィールドのみを抽出できますが、これを完成したjson配列に結合する方法がわかりません。

#!/bin/sh
input="pssh_result.txt"
while IFS= read -r line; do
    # echo "$line"
    if jq -e . >/dev/null 2>&1 <<<"$line"; then
        read field1 field3 <<<$(echo $(echo $line |
            jq -r '.field1, .field3'))
        example_item=$(jq --null-input \
            --arg field1 "$field1" \
            --arg field3 "$field3" \
            '{"alias1": $field1, "alias2": $field3}')

        echo $example_item
    fi
done <"$input"

出力は次のとおりです

sh test.sh 
{ "alias1": "value11", "alias2": "value13" }
{ "alias1": "value21", "alias2": "value23" }

しかし、私は欲しいマージ後で処理のために第三者に送信できるように、大きなjson配列に入れます。希望する結果次のように

[
    {
        "alias1": "value11",
        "alias2": "value13"
    },
    {
        "alias1": "value21",
        "alias2": "value23"
    }
]

配列に入れてそのように渡すことも考えてみましたが、期待どおりにjoin(arr,",")動作しませんでした。

私が望む結果をどのように取得できますか?これにご協力いただきありがとうございます。

答え1

入力が次のようになるとします。

[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}

(JSONオブジェクトを含む行で壊れたJSONを修正しました。)

...その後、以下を使用して必要な行を抽出できますgrep

grep '^{' file

または

grep -v -F '[SUCCESS]' file

または同様のgrepコマンド。

その後、JSONオブジェクトストリームの解析を使用すると、jq -s自動的に配列に読み込むことができます。これにより、次のようにデータを処理できます。

grep '^{' file | jq -s 'map({ alias1: .field1, alias2: .field3 })'

上記の入力を使用すると、file次のものが生成されます。

[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

既存の初期入力解析を変更することに興味がなく、出力を配列に保存するには、次のように渡しますjq -s .

$ cat file
{ "alias1": "value11", "alias2": "value13" }
{ "alias1": "value21", "alias2": "value23" }
$ jq -s . file
[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

読む価値のあるハッカーまっすぐ元のファイルのデータをjq生の文字列として読み取り、有効なJSONに変換してエラーを削除します。

$ cat file
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}
$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null
{
  "alias1": "value11",
  "alias2": "value13"
}
{
  "alias1": "value21",
  "alias2": "value23"
}

その後、配列として収集できます。

$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null | jq -s .
[
  {
    "alias1": "value11",
    "alias2": "value13"
  },
  {
    "alias1": "value21",
    "alias2": "value23"
  }
]

jq最初のjq呼び出しが入力をJSONとfromjson配列(または単一のオブジェクト以外の構造)に変換しようとすると早期に終了するため、ここでは2つの別々の呼び出しを実行する必要があります。

関連情報