将 bash 数组转换为 json 数组并使用 jq 插入文件
Convert bash array to json array and insert to file using jq
给定一个 bash 数组,如何将其转换为 JSON 数组以便使用 jq 输出到文件?
另外:有没有办法保持 server_nohup 数组不变,而不是每次都重写整个 json 文件?
newArray=(100 200 300)
jq -n --arg newArray $newArray '{
client_nohup: [
$newArray
],
server_nohup: [
]
}' > $projectDir/.watch.json
当前输出:
{
"client_nohup": [
"100"
],
"server_nohup": []
}
期望的输出:
{
"client_nohup": [
100,
200,
300
],
"server_nohup": []
}
(1) 如果 newArray 中的所有值都是有效的 JSON 值而没有空格,那么您可以将这些值作为流进行管道传输,例如
newArray=(100 200 300)
echo "${newArray[@]}" |
jq -s '{client_nohup: ., server_nohup: []}'
(2)
现在假设您只想更新文件中的 "nohup" 对象,比如 nohup.json:
{ "client_nohup": [], "server_nohup": [ "keep me" ] }
因为你使用的是bash,你可以这样写:
echo "${newArray[@]}" |
jq -s --argjson nohup "$(cat nohup.json)" '
. as $newArray | $nohup | .client_nohup = $newArray
'
输出
(1)
{
"client_nohup": [
100,
200,
300
],
"server_nohup": []
}
(2)
{
"client_nohup": [
100,
200,
300
],
"server_nohup": [
"keep me"
]
}
其他情况
有志者事竟成:-)
例如,请参阅 How to format a bash array as a JSON array 中已接受的答案(尽管这不是一个完全通用的解决方案)。
有关通用解决方案,请参阅 jq 常见问题解答 : How can a variable number of arguments be passed to jq? How can a bash array of values be passed in to jq as a single argument?
https://github.com/stedolan/jq/wiki/FAQ
通用解决方案
需要说明的是,如果已知数组值有效 JSON,则有几个不错的选择;如果数组值是任意 bash 字符串,那么使用 jq 处理它们的唯一有效、通用的方法是使用 -R
jq 选项(例如与 -s 结合使用),然后 (bash) 字符串将全部作为 JSON 字符串读入,因此任何预期的类型信息都将丢失。 (这里的重点取决于 bash 字符串不能包含 NUL 字符的技术性。)
通常,为了减轻后一种担忧,可以将数字字符串转换为 JSON 数字,例如使用 jq 习语:(tonumber? // .)
.
一般来说,唯一真正安全的方法是多次调用 jq
,将每个元素添加到前一个命令的输出中。
arr='[]' # Empty JSON array
for x in "${newArray[@]}"; do
arr=$(jq -n --arg x "$x" --argjson arr "$arr" '$arr + [$x]')
done
这可确保 bash
数组的每个元素 x
在添加到 JSON 数组之前已正确编码。
不过,这很复杂,因为 bash
不区分数字和字符串。这会将您的数组编码为 ["100", "200", "300"]
,而不是 [100, 200, 300]
。最后,您需要了解数组包含的内容,并相应地对其进行预处理。
给定一个 bash 数组,如何将其转换为 JSON 数组以便使用 jq 输出到文件?
另外:有没有办法保持 server_nohup 数组不变,而不是每次都重写整个 json 文件?
newArray=(100 200 300)
jq -n --arg newArray $newArray '{
client_nohup: [
$newArray
],
server_nohup: [
]
}' > $projectDir/.watch.json
当前输出:
{
"client_nohup": [
"100"
],
"server_nohup": []
}
期望的输出:
{
"client_nohup": [
100,
200,
300
],
"server_nohup": []
}
(1) 如果 newArray 中的所有值都是有效的 JSON 值而没有空格,那么您可以将这些值作为流进行管道传输,例如
newArray=(100 200 300)
echo "${newArray[@]}" |
jq -s '{client_nohup: ., server_nohup: []}'
(2) 现在假设您只想更新文件中的 "nohup" 对象,比如 nohup.json:
{ "client_nohup": [], "server_nohup": [ "keep me" ] }
因为你使用的是bash,你可以这样写:
echo "${newArray[@]}" |
jq -s --argjson nohup "$(cat nohup.json)" '
. as $newArray | $nohup | .client_nohup = $newArray
'
输出
(1)
{
"client_nohup": [
100,
200,
300
],
"server_nohup": []
}
(2)
{
"client_nohup": [
100,
200,
300
],
"server_nohup": [
"keep me"
]
}
其他情况
有志者事竟成:-)
例如,请参阅 How to format a bash array as a JSON array 中已接受的答案(尽管这不是一个完全通用的解决方案)。
有关通用解决方案,请参阅 jq 常见问题解答 : How can a variable number of arguments be passed to jq? How can a bash array of values be passed in to jq as a single argument?
https://github.com/stedolan/jq/wiki/FAQ
通用解决方案
需要说明的是,如果已知数组值有效 JSON,则有几个不错的选择;如果数组值是任意 bash 字符串,那么使用 jq 处理它们的唯一有效、通用的方法是使用 -R
jq 选项(例如与 -s 结合使用),然后 (bash) 字符串将全部作为 JSON 字符串读入,因此任何预期的类型信息都将丢失。 (这里的重点取决于 bash 字符串不能包含 NUL 字符的技术性。)
通常,为了减轻后一种担忧,可以将数字字符串转换为 JSON 数字,例如使用 jq 习语:(tonumber? // .)
.
一般来说,唯一真正安全的方法是多次调用 jq
,将每个元素添加到前一个命令的输出中。
arr='[]' # Empty JSON array
for x in "${newArray[@]}"; do
arr=$(jq -n --arg x "$x" --argjson arr "$arr" '$arr + [$x]')
done
这可确保 bash
数组的每个元素 x
在添加到 JSON 数组之前已正确编码。
不过,这很复杂,因为 bash
不区分数字和字符串。这会将您的数组编码为 ["100", "200", "300"]
,而不是 [100, 200, 300]
。最后,您需要了解数组包含的内容,并相应地对其进行预处理。