# Denote the input of recursively_reduce(f) by $in.
# Let f be a filter such that for any object o, (o|f) is an array.
# If $in is an object, then return $in|f;
# if $in is a scalar, then return [];
# otherwise, collect the results of applying recursively_reduce(f)
# to each item in $in.
def recursively_reduce(f):
if type == "object" then f
elif type == "array" then map( recursively_reduce(f) ) | add
else []
end;
$ eval "$(jq -r 'to_entries? | map("set -A jsn_\(.key|@sh) -- \(.value|@sh)") | .[]' <test.jsn)"
$ echo $jsn_x
test
$ echo $jsn_foo = ${jsn_foo[0]} but not ${jsn_foo[1]}
bar = bar but not baz
set -o pipefail
if ! vars=$(curl "${curlopts[@]}" "$url" | jq -r '
if . == null then
null
else
to_entries | map(
select(IN(.key;
"foo", "val", "var"
)) | "set -A jsn_\(.key | @sh) -- \(.value | @sh)"
) | .[]
end
'); then
echo >&2 "E: no API response"
exit 1
fi
if [[ $vars = null ]]; then
echo >&2 "E: empty API response"
exit 1
fi
eval "$vars"
echo "I: API response: var=$jsn_var"
for x in "${jsn_foo[@]}"; do
echo "N: got foo '$x'"
done
6条答案
按热度按时间djmepvbi1#
您可以尝试:
字符串
下面是一个演示:
型
a9wyjsp72#
有没有什么方法可以递归地做这个?
下面是一个函数,它可以做你想要的:
字符串
示例:发出键=值对
型
更新:在jq 1.5发布后,walk/1作为jq定义的内置添加。它可以与上述定义的kv一起使用,例如具体如下:
型
使用上述输入,结果将是:
[[“a=1”],[[“B=2”,“c=3”]
要“平坦化”输出,可以使用flatten/0。下面是一个完整的例子:
型
输入:
型
输出量:
型
b1zrtrql3#
顺便说一句,基于@aioobe的出色回答。如果你需要所有的键都是大写的,你可以使用
ascii_upcase
来修改他的例子:字符串
示例
我有一个类似于你的场景,但在创建访问AWS的环境变量时,我希望将所有键都大写。
型
参考资料
yk9xbfzb4#
没有
jq
,我可以使用grep
和sed
导出json中的每一个项目,但这只适用于简单的情况,我们有键/值对字符串
下面是一个响应示例:
型
yk9xbfzb5#
要在aaiobe’s answer的基础上添加,这里有一些事情可以使它更安全/更灵活地用途:
null
安全性的问号jsn_
修复命名空间的结果变量,以避免他们覆盖你的正常变量字符串
上面的输出是Korn Shell数组(对于
mksh
和AT&Tksh
)。如果你更喜欢/需要GNU bash风格的数组(也被许多其他最近的shell版本支持),用途:型
在所有后续的例子中,我将使用Korn Shell变体,但应用上述两个变体之间的差异将适用于它们。
在这两种情况下,你都得到了数组,但是解引用数组本身与解引用它的元素#0是一样的,所以即使对于单个值,这也是安全的:
型
但也有一个缺点:只为
sh
编写的脚本没有数组,因此您需要以bash
、ksh88
、ksh93
、mksh
、zsh
(可能还有其他)或它们的公共子集(所有这些都支持[[ … ]]
;除了ksh88
之外,所有的都应该支持GNU bash风格的数组)。两个进一步的改进:
null
处理(见下文)型
在本例中,只允许使用密钥
foo
、val
(此处不存在)和var
。这可以用于例如过滤掉其值不是简单值或简单值的一维JSONArray的键,因此结果是安全的¹。你可以用这个,例如。如下所示:
型
①虽然
jq
会抛出错误,除非使用问号,但如果确实存在多维数组或其他诡计,则失败模式就不那么好了:型
如果你不知道你的JSON是否正常,一定要测试一下。见鬼,测试一下,总是这样; catch
jq
错误退出代码。注意上面例子中的set -o pipefail
,如果shell支持(最新的shell支持),如果cURL或jq
失败(或者两者都失败),整个命令替换将失败;否则,你必须将cURL输出重定向到一个临时文件,检查curl
的errorlevel,然后在命令替换中对临时文件运行jq并检查其退出状态(如果你希望在错误消息中区分它们,你仍然必须精确地这样做)。wixjitnu6#
这里有一个紧凑的解决方案:第一个月
字符串