はJQ

2016-12-27 5 views
1

例JSONファイル内の正確なパスなしサブキーを置き換えますか?はJQ

{ 
    "u": "stuff", 
    "x": [1,2,3], 
    "y": { 
    "field": "value" 
    }, 
    "z": { 
    "zz": { 
     "name": "something", 
     "more": "stuff" 
    }, 
    "randomKey": { 
     "name": "something", 
     "random": "more stuff" 
    } 
    } 
} 

ダイレクトパスでは簡単ですが、親キー(これらの場合はzとrandomKey)が変化します。

私が何かしようとした:、

jq '.z | .. | .name? |= "something"' file.json 

をそして、それが発生した場所に「名前」フィールドを変更することが許容される場合、それは...

答えて

1

を名前を更新するだけでなく、すべての再帰的なものを入れていますあなたはwalk/1を使用することができます。

walk(if type == "object" and has("name") then .name = "something" else . end) 

JQ 1.5がリリースされた後walk/1だけJQに含まれていたことに注意してください。 jqにそれがない場合は、たとえば、jq FAQでその定義を見つけることができます。あなたが唯一の「Z」文脈で「名前」フィールドを変更したい場合は

、そして考える:

.z |= with_entries(if .value.name? 
        then .value.name = "something" 
        else . end) 
+0

完璧、ありがとう! –

1

z内のすべての値は、nameプロパティを持っていると仮定すると、あなたはこれを行うことができます:

$ jq --arg newname 'something' '.z[].name = $newname' input.json 

オブジェクトに[]を使用すると、そのオブジェクトに含まれるすべての値が得られます。これらの値のそれぞれについて、単純にnameを新しい名前に設定しました。


更新されるものをさらに選択する必要がある場合は、更新するオブジェクトに条件を追加する必要があります。一般的に、私はピークのアプローチを使用したいが、ここでは、すでにnameプロパティを持つオブジェクトを更新したいと仮定すると、それは最初のアプローチと同様の構造を使用して達成することができ、別の方法です:

$ jq --arg newname 'something' '(.z[] | select(has("name")).name) = $newname' input.json 

それが重要です割り当てのLHSをカッコで囲むには、割り当て前にコンテキストを変更する必要はありません。それ以外の場合、結果の残りの部分は表示されません。