jqを使用して特定の行の前にjsonチャンクを追加する

jqを使用して特定の行の前にjsonチャンクを追加する

すでにjsonファイルがあり、jqを使用してファイルを開いて編集したいシナリオがあります。

jsonファイル(temp.json):

{
  "a":{
    "keya" : "abc",
    "keyb" : "xyz"
  },
  "c":{
    "keyc" : "yyy"
  }
}

cここでは、検索を通じてブロックの前に別のjsonオブジェクトを追加したいと思います。デフォルトでは、最後のオブジェクトの前に値を追加します。この場合、最後のオブジェクトは常にc

  "b":{
    "keyb" : "yop"
  }

私はjqを使用して挿入ブロックを実装しましたが、目的の場所に挿入されませんでした。 jq '. |= . + {"b":{ "keyb" : "yop" }}' temp.json

どんな助けでもいいでしょう。

答え1

jqキーをソートするために使用できるオプション-S。例えば

$ jq -S '. |= . + {"b":{ "keyb" : "yop" }}' temp.json
{
  "a": {
    "keya": "abc",
    "keyb": "xyz"
  },
  "b": {
    "keyb": "yop"
  },
  "c": {
    "keyc": "yyy"
  }
}

答え2

オブジェクトはソートされていないキーの集まりです。キーの順序本当に気にしません。JSONドキュメントを読むアプリケーションに。ソートされたデータが必要な場合は、配列の使用を検討してください。

以下はステップバイステップのソリューションです。最終コードは最後にあります。

配列は順序付けされているため、次を使用して最上位オブジェクトをキーと値の順序付き配列に変換できますto_entries

$ jq 'to_entries' file
[
  {
    "key": "a",
    "value": {
      "keya": "abc",
      "keyb": "xyz"
    }
  },
  {
    "key": "c",
    "value": {
      "keyc": "yyy"
    }
  }
]

この配列の最後の要素の前にコンテンツを挿入できます。ここでは、最初の要素(最後の元の要素を除くすべての要素.[:-1])、新しい要素、および最後の元の要素()のフラグメントを使用して.[-1]「アイテム」配列を上書きします。

$ jq 'to_entries | . |= .[:-1] + [ { key: "b", value: { keyb: "yop" } }, .[-1] ]' file
[
  {
    "key": "a",
    "value": {
      "keya": "abc",
      "keyb": "xyz"
    }
  },
  {
    "key": "b",
    "value": {
      "keyb": "yop"
    }
  },
  {
    "key": "c",
    "value": {
      "keyc": "yyy"
    }
  }
]

from_entriesその後、キーの順序を変更せずに元の形式に戻すことができます。

$ jq 'to_entries | . |= .[:-1] + [ { key: "b", value: { keyb: "yop" } }, .[-1] ] | from_entries' file
{
  "a": {
    "keya": "abc",
    "keyb": "xyz"
  },
  "b": {
    "keyb": "yop"
  },
  "c": {
    "keyc": "yyy"
  }
}

コマンドラインから新しい要素をキーとJSONオブジェクトに渡します。

$ jq --arg key 'yellow' --argjson value '{ "type": "color" }' 'to_entries | . |= .[:-1] + [ { key: $key, value: $value }, .[-1] ] | from_entries' file
{
  "a": {
    "keya": "abc",
    "keyb": "xyz"
  },
  "yellow": {
    "type": "color"
  },
  "c": {
    "keyc": "yyy"
  }
}

関連情報