次のjsonファイルから
{
"email": "xxx",
"pass": "yyy",
"contact": [
{
"id": 111,
"name": "AAA"
}
],
"lname": "YYY",
"name": "AAA",
"group": [
{
"name": "AAA",
"lname": "YYY",
}
],
「name」キーを見つけて、その値を「XXX」に置き換える必要があります。どのjqコマンドがこれを実行しますか?
答え1
jqの割り当てタスクは、複数の場所で同時に更新を実行でき、この状況のために設計されています。あなたはそれを使用することができます
jq '(.. | .name?) |= "XXXX"'
到着どこでも「名前」という名前のすべてのフィールドを見つけ、各フィールドの値を一度に置き換えます。「XXXX」で結果オブジェクトを出力します。
これはただ..|.a?
出てきた再帰下降文書結合するジョブの更新。
それを使う再帰下降演算子..
ツリー内の各値を見つけ、各値から「名前」フィールドを抽出します。そして.name
、一致しない値に対するエラーを抑制します。?
その後、「XXXX」を使用して、これらすべての場所のオブジェクトを一度に更新します。代入演算子の更新|=
、新しいオブジェクトを出力します。
これはファイル構造に関係なく機能し、すべての場所のすべての名前フィールドを更新します。
または、ファイルには常にこの構造があります。変更したい特定の「名前」フィールド、以前の名前だけでなく、名前を一覧表示してグループに割り当てることもできます。
jq '(.name, .contact[].name, .group[].name) |= "XXXX"'
これは同じ割り当てを実行します。
- 最上位オブジェクトの「名前」フィールドです。
- 「名前」フィールドすべて連絡先配列のオブジェクト
- 「グループ」配列内の各オブジェクトの「名前」フィールド。
一度に完了します。これは、ファイルに次のものがある場合に特に便利です。その他名前フィールドが無関係な場所にあり、変更したくありません。指定された3つのセットの位置のみを探して同時に更新します。
値がここと同じリテラルの場合簡単な割り当てと=
また、動作し、キャラクターを保存します。(..|.name?)="XXXX"
- 最上位オブジェクト全体に基づいて値を計算する場合でも、この機能が必要です。古い名前に基づいて新しい名前を計算するには:必要|=
何を使用するのかわからない場合は、一般的に極端なケースでより良い動作を|=
示します。
お持ちの場合複数の交換が必要、一緒に接続することができます。
jq '(..|.name?) = "XXXX" | (..|.lname?) = "1234"'
「name」フィールドと「lname」フィールドはどこでも更新され、更新されたオブジェクト全体が一度出力されます。
効果があるかもしれない他のアプローチ:
何を選択するかを非常に具体的に指定することもできます。
(..|objects|select(has("name"))).name |= "XXXX"`
すべてを検索し、オブジェクトのみを検索し、「名前」を持つオブジェクトのみを検索し、そのオブジェクトの名前フィールドを探し、以前と同じ更新を実行します。
jqの開発バージョンを実行している場合(可能性なし)
walk
機能次の操作も実行されますwalk(.name?="XXXX")
。他のすべてのバージョンは、最新リリースバージョン1.5で実行されます。複数の更新の別のタイプは次のとおりです。
jq '(..|select(has("name"))?) += {name: "XXXX", lname: "1234"}'
それはすべてを見つけるそして名前を指定し、各オブジェクトに「name」と「lname」を設定します。算術更新の割り当て*=
そして+
オブジェクトのマージ動作。
答え2
jq
機能に応じて使用walk
(最新バージョンが必要):
jq 'walk(.name?="XXX")' file
jq
その機能をサポートしていない場合は、walk
次のように定義してください。
jq '
# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
walk(.name?="XXX")
' file
答え3
または、jtc
以下に基づくソリューション:
bash $ jtc -w'<name>l+0' -u'"XXX"' your.json
{
"contact": [
{
"id": 111,
"name": "XXX"
}
],
"email": "xxx",
"group": [
{
"lname": "YYY",
"name": "XXX"
}
],
"lname": "YYY",
"name": "XXX",
"pass": "yyy"
}
bash $