我正在尝试使用bash创建一个字符串变量,该变量将在jq中使用,以向json文件添加新元素。但这在转义我的双引号。参见下面的“错误输出”。我期望在“预期输出”下面显示输出。用bash变量向文件名添加更多字段的正确方法是什么?
我的输入json文件(input.json):
'
我的bash脚本:
<a href="#" onclick="$('#element').dialog('open');" ></a>
错误的输出:
{
"##_Comment1": "Inputs",
"filename": [
"file1",
"file2",
"file3",
"file4"
]
}
正确的输出:
#!/bin/bash
update_list='"abc","efg"'
cat input.json | jq --arg args "$update_list" '.["filename"] += [$args]'
答案 0 :(得分:1)
稍微放松一下自己的情况:
$ jq --arg args '"abc","efg"' '.["filename"] += [$args]' <<< '{"filename":[]}'
{
"filename": [
"\"abc\",\"efg\""
]
}
在这里,我们正在args
引擎中有效地将jq
分配给字符串:
args = "\"abc\",\"efg\""
如果要将args
设置为列表/数组,则需要采取另一种方法。
您可以格式化JSON参数并使用--argjson
:
$ jq --argjson args '["abc","efg"]' '.["filename"] += $args' <<< '{"filename":[]}'
{
"filename": [
"abc",
"efg"
]
}
或者您可以将update_list
放入数组并循环:
update_list=()
update_list+=("abc")
update_list+=("efg")
echo '{"filename":[]}' > test
for i in "${update_list[@]}"; do
jq --arg update_item "${i}" '.["filename"] += [ $update_item ]' < test \
| sponge test
done
$ cat test
{
"filename": [
"abc",
"efg"
]
}
答案 1 :(得分:1)
在原始问题中,update_list
是用引号引起来的字符串的逗号分隔列表,如果这些字符串也是JSON字符串,则以下解决方案将起作用:
jq --arg args "$update_list" '
.["filename"] += ($args|split(",")|map(fromjson))'
如果可以将update_list
作为JSON数组使用,那么@Attie的第一个解决方案就是解决之道。
如果update_list
是bash数组,则涉及对每个数组元素一次调用jq的解决方案是不必要的(并且可能令人尴尬地)效率低下;建议的解决方案也可能会造成问题,因为更新不是原子的。有更好的选择。例如,jq FAQ提到了一种技术,当将该技术应用于当前问题时,它会产生以下解决方案:
jq --argjson args "$(printf '%s\n' "${update_list[@]}" | jq -nR '[inputs]')" '
.["filename"] += $args'
或者出于鲁棒性考虑,可以使用NUL作为分隔符:
jq --argjson args "$(printf '%s\0' "${update_list[@]}" | jq -sR 'split("\u0000")')" '
.["filename"] += $args'