2017-03-15 52 views
1

我已經閱讀了幾乎所有我能找到的問題與相同的一般前提下,我已經接近三個不同的時間,但我不能使這項工作。追加新的密鑰對JSON文件與jq

給定一個名爲parameters.json的JSON文件,它帶有這樣的密鑰對; (縮短共享的目的)

[ 
    { 
    "ParameterKey": "Foo1", 
    "ParameterValue": "Bar1" 
    }, 
    { 
    "ParameterKey": "Foo2", 
    "ParameterValue": "Bar2" 
    } 
] 

我要添加另一個密鑰對,說

{ 
    "ParameterKey": "Foo3", 
    "ParameterValue": "Bar3" 
    } 

所以我最終喜歡

[ 
    { 
    "ParameterKey": "Foo1", 
    "ParameterValue": "Bar1" 
    }, 
    { 
    "ParameterKey": "Foo2", 
    "ParameterValue": "Bar2" 
    }, 
    { 
    "ParameterKey": "Foo3", 
    "ParameterValue": "Bar3" 
    } 
] 

使用案例文件&嘗試

我正在寫一個bash腳本來複制和更新AWS的參數文件 - 這是密鑰對進來。我們有一個新的密鑰對,當它們被複制時,需要將它添加到任何現有的文件中。我可以得到如果/然後做得很好,它實際上是增加了一個新的密鑰對,這對我來說很困難。

一噸的google搜索,我結束了這個笨重的解決辦法,我真的不明白,並同時生成密鑰對蠻好的,不添加回parameters.json

item='{"ParameterKey": "RTSMSnapshotID"}' 

jq --argjson item "$item" '$item + {"ParameterValue": ""}' parameters.json 

我在命令行中將密鑰對正確地打印回給我,所以我想添加| sponge parameters.json,但那會給我一個空文件。

我也考慮過一個sed解決方法,修剪文件的最後一行,然後附加新的密鑰對(和EOF),但當然sed不能很好地適應換行符,並且我無法使其工作。

我很喜歡在bash和jq中使用任何東西的解決方案。我仍然是一個bash/jq noob,所以我對此有詳細的解釋。

回答

2

使用argjson的想法是正確的,但語法是如下的jq-1.5

jq --argjson obj '{ "ParameterKey": "Foo3", "ParameterValue": "Bar3" }' '. + [$obj]' < json 
[ 
    { 
    "ParameterKey": "Foo1", 
    "ParameterValue": "Bar1" 
    }, 
    { 
    "ParameterKey": "Foo2", 
    "ParameterValue": "Bar2" 
    }, 
    { 
    "ParameterKey": "Foo3", 
    "ParameterValue": "Bar3" 
    } 
] 

檢查jq-documentation有關++=運營商的更多信息。

我不知道的方式jq本身要做到這一點,但您可以使用一個整潔bash伎倆要做到這一點,

jq --argjson obj '{ "ParameterKey": "Foo3", "ParameterValue": "Bar3" }' '. + [$obj]' <json> temp && mv temp json 
+0

這確實增加了新的密鑰對預期(謝謝!),但打印輸出到命令行。我如何將它重新輸入'parameters.json'? – Alex

+1

在jq常見問題頁面(https://github.com/stedolan/jq/wiki/FAQ)上,搜索:-i – peak

+1

以防萬一有人需要使用此功能 - 事實證明,您可以添加'|海綿parameters.json'如果你有工具安裝一個簡單的解決方法。 – Alex

1

如果你有一個文件,一個JSON陣列(說parameters.json) ,以及一個或多個附加文件(比如說文件* .json),這些文件需要附加到第一個文件中的數組,並且如果您想覆蓋第一個文件,則這是一個相當狡猾的解決方案,但需要jq 1.5或更高版本:

$ jq 'reduce inputs as $in (.; . + [$in])' parameters.json file*.json | 
    sponge parameters.json 

注意th在使用這種方法時,每個輔助文件中的每個頂層JSON實體都將分別附加到數組中。

是什麼讓這個有點狡猾的是inputs這裏沒有使用-n選項。

既然你提到bash,請注意,如果任何的「文件*以.json」的來源是一個過程,你可以使用<(...),而不是指定一個文件名,如:

$ jq 'reduce inputs as $in (.; . + [$in])' parameters.json <(curl -Ss ...) | 
    sponge parameters.json 

如果你不」噸有sponge,那麼你可以使用這個成語:

jq ..... > OUT && mv IN OUT 
+0

我特別需要一個沒有中間文件的解決方案,因爲這個過程發生在Jenkins,並且一旦涉及文件,它就會混亂工作區或需要git簽出。不過,我贊成答案;可能對別人使用不同用例有用。 – Alex

+0

@Alex你可以使用<(...)? – peak