JQはコンマなしのJSON行を返します

JQはコンマなしのJSON行を返します

明確に言うと、ここでは別の静的 JSON ファイルに書き込まれる疑似 JSON 出力が必要です。つまり、配列などにラップされるのではなく、出力内の各エンティティの後に不足しているコンマを取得するだけです。

現在、私の質問は次のとおりです:

.[] | select(.auditId == "categories") |
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
  }
}

出力は次のようになります:

{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*performance:* 1 (expected 0.8)"
  }
}
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*accessibility:* 1 (expected 0.9)"
  }
}
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*best-practices:* 0.96 (expected 0.9)"
  }
}
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*seo:* 0.64 (expected 0.5)"
  }
}

実際に私が望んでいるのは:

{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*performance:* 1 (expected 0.8)"
  }
},
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*accessibility:* 1 (expected 0.9)"
  }
},
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*best-practices:* 0.96 (expected 0.9)"
  }
},
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*seo:* 0.64 (expected 0.5)"
  }
},

各エンティティの後のカンマに注意してください。これは私を悩ませています。join(", ")さまざまな場所にカンマを追加しようとしましたが、配置場所によっては最終出力に何も影響しないか、コンパイルに失敗します。

データが含まれたjqplayはこちらhttps://jqplay.org/s/xx3F_IWn03g


元の入力JSON:

[
  {
    "name": "minScore",
    "expected": 0.8,
    "actual": 1,
    "values": [
      1,
      1,
      1
    ],
    "operator": ">=",
    "passed": true,
    "auditProperty": "performance",
    "auditId": "categories",
    "level": "error",
    "url": "http://localhost:8080/page2"
  },
  {
    "name": "minScore",
    "expected": 0.9,
    "actual": 1,
    "values": [
      1,
      1,
      1
    ],
    "operator": ">=",
    "passed": true,
    "auditProperty": "accessibility",
    "auditId": "categories",
    "level": "error",
    "url": "http://localhost:8080/page2"
  },
  {
    "name": "minScore",
    "expected": 0.9,
    "actual": 0.96,
    "values": [
      0.93,
      0.96,
      0.96
    ],
    "operator": ">=",
    "passed": true,
    "auditProperty": "best-practices",
    "auditId": "categories",
    "level": "error",
    "url": "http://localhost:8080/page2"
  },
  {
    "name": "minScore",
    "expected": 0.5,
    "actual": 0.64,
    "values": [
      0.64,
      0.64,
      0.64
    ],
    "operator": ">=",
    "passed": true,
    "auditProperty": "seo",
    "auditId": "categories",
    "level": "error",
    "url": "http://localhost:8080/page2"
  }
]

答え1

あなたはそうしたいと思っているようです修正するauditId文字列に設定されているエントリcategories。あなたがやっていることは抽出する最上位の配列からそれらの要素を取得して変更します。これにより、オブジェクトのセット (配列ではありません) が生成されます。

|配列から要素を抽出するために使用する代わりに、|=要素を変更します。結果の配列を別のファイルの JSON 構造に適切に挿入する方法については、この回答の最後を参照してください。

だから、

.[] |= (
    select(.auditId == "categories") |
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
        }
    }
)

.[]あるいは、まったく使用せず、代わりにmap()最上位配列の各要素に対する式:

map(
    select(.auditId == "categories") |
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
        }
    }
)

これらの式により、次のような要素の配列が生成されます。

[
  {
    "type": "section",
    "text": {
      "type": "mrkdwn",
      "text": "*performance:* 1 (expected 0.8)"
    }
  },
  {
    "type": "section",
    "text": {
      "type": "mrkdwn",
      "text": "*accessibility:* 1 (expected 0.9)"
    }
  },
  {
    "type": "section",
    "text": {
      "type": "mrkdwn",
      "text": "*best-practices:* 0.96 (expected 0.9)"
    }
  },
  {
    "type": "section",
    "text": {
      "type": "mrkdwn",
      "text": "*seo:* 0.64 (expected 0.5)"
    }
  }
]

この配列を別のファイル内の既存の配列に追加するには、次のようにします (arrayの最上位にキーがありotherfile、入力が にあると仮定しますinputfile。キーがまだ存在しない場合は作成されます)。

jq '.array += ( input |
    map(
        select(.auditId == "categories") |
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
            }
        }
    )
)' otherfile inputfile

が実行されるとinput、コマンド ラインの 2 番目のファイルから配列が読み取られます。

既存のキーの値を追加するのではなく、置き換える場合は、+=に変更します。=array

答え2

はい、それが[]イテレータの機能です。それぞれに対して 1 つの JSON ファイルを取得します。配列を取得するには、式全体を で[...]囲んで配列を作成するか、要素を反復処理map()する代わりに を使用して入力配列をその場で変更します[]

$ echo '[1,2,3,4]' | jq '.[]|select(.<3)'
1
2
$ echo '[1,2,3,4]' | jq '[.[]|select(.<3)]'
[
  1,
  2
]
$ echo '[1,2,3,4]' | jq 'map(select(.<3))'
[
  1,
  2
]

[,で囲まずにコンマで区切られた要素を配列にする]と無効な json になりますが、それが目的であれば、パイプを使用してsed '1d;$d'最初の行と最後の行を削除できます。

関連情報