![](/img/trans.png)
[英]Assigning jq output to bash array when json value contains spaces
[英]Setting a value in jq when path and value are env variables is not working as expected (bash)
我想使用 shell 腳本中的 jq 在 JSON 嵌套對象中設置一個值。 如果我使用顯式值,它會按預期設置 JSON 值。 但是當我使用變量時,它會添加(如果奇怪的話)一個新的鍵/值。
最終目標是在給定任意、適合 jp 的顯式路徑的情況下以任意 JSON 設置鍵的值。 無需選擇/匹配。 我們還假設所有值都是字符串。 我得到--args 和--argsjson 之間的差異。
但讓我們從簡單的開始。 這是我的測試:
echo $JSON
{
"make" : "ford",
"model" : "ranger",
"year" : "2020"
"options" : {
"cylinders" : "v6"
"cab" : "true"
}
}
假設我想設置options.cylinders = "v4"
這有效:
echo $JSON | jq 'options.cylinders = "v4"'
這也有效:
echo $JSON | jq --arg value "v4" '.options.cylinders = $value'
讓我們用變量替換值。 這行得通。
cyl="v4"
echo $JSON | jq --arg value "$cyl" '.options.cylinders = $value'
讓我們用變量替換路徑。 它抱怨,但只是為了讓你知道我去過哪里:
cyl="v4"
path="options.cylinder"
echo $JSON | jq --arg path "$path" --arg value "$cyl" '.$path = $value'
這會引發錯誤,但可以通過以下方式糾正:
cyl="v4"
path="options.cylinder"
echo $JSON | jq --arg path "$path" --arg value "$cyl" '.[$path] = $value'
現在你會認為前者會起作用。 它成功了,但是它將整個路徑作為鍵添加了值,而不是將其設置為路徑所在的位置。 結果是:
{
"make" : "ford",
"model" : "ranger",
"year" : "2020"
"options" : {
"cylinders" : "v6"
"cab" : "true"
}
"options.cylinders" : "v4"
}
我也嘗試過使用 path() 函數,將它傳遞給一個 bash 數組。 這也不起作用。
cyl="v4"
path=(".", "options", "cylinders")
echo "${JSON}" | jq --arg key $path --arg value "${cyl}" 'path($key; $value)'
我得到:
jq: error: path/2 is not defined at <top-level>, line 1:
path($key; $value)
jq: 1 compile error
如果我刪除“。” 從路徑中,它只是向上移動錯誤:
jq: error: path/1 is not defined at <top-level>, line 1:
我已閱讀所有文檔。 我確信我已經嘗試過其他的東西,但我在這一點上被難住了。 那么......我在這里錯過了什么? 關? 想法?
感謝@pmf,所以讓它成為一個維基
#!/bin/sh
# Sets the source JSON in a shell variable
json='{
"make": "ford",
"model": "ranger",
"year": "2020",
"options": {
"cylinders": "v6",
"cab": "true"
}
}'
# Parameters to modify the source JSON
path='options.cylinders'
cyl='v4'
# Process with jq
jq \
--null-input \
--argjson json "$json" \
--arg path "$path" \
--arg value "$cyl" \
'$json | setpath($path / "."; $value)'
setpath(path_array; value)
將路徑元素的值設置為數組。
所以$path
字符串是: /
除以它的.
點,把它變成一個數組。
讓我們演示一下:
jq -n '"options.cylinders" / "."'
將上面的字符串轉換為適合從點分隔字符串創建路徑的數組:
[
"options",
"cylinders"
]
所以當它運行時:
setpath("options.cylinders" / "."; "v4")
它擴展為:
setpath(["options","cylinders"]; "v4")
這與靜態路徑值分配完全相同:
.options.cylinders = "v4"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.