如何在 jq 中将 JSON 对象转换为 key=value 格式?
Posted
技术标签:
【中文标题】如何在 jq 中将 JSON 对象转换为 key=value 格式?【英文标题】:How to convert a JSON object to key=value format in jq? 【发布时间】:2014-10-12 05:37:54 【问题描述】:在 jq 中,如何将 JSON 转换为带有key=value
的字符串?
发件人:
"var": 1,
"foo": "bar",
"x": "test"
收件人:
var=1
foo=bar
x=test
【问题讨论】:
【参考方案1】:你可以试试:
jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
这是一个演示:
$ cat test.json
"var": 1,
"foo": "bar",
"x": "test"
$ jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json
foo=bar
var=1
x=test
【讨论】:
有什么办法可以递归地做到这一点? 有一个递归函数......但我想你需要说出要递归的字段。您是否有要递归的固定字段,或者只是“任何作为对象的值”? 没有特别的。我将尝试一种不同的递归方法。 我发现这个问题希望将 json 对象转换为键/值对数组 --to_entries
正是我所需要的。
@aioobe 有没有办法可以将键大写?我试过\(.key | tr a-z A-Z)
无济于事。【参考方案2】:
有什么办法可以递归地做到这一点?
这是一个可以做你想做的功能:
# 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;
示例:发出 key=value 对
def kv: to_entries | map("\(.key)=\(.value)");
[ "a":1, [["b":2, "c": 3]] ] | recursively_reduce(kv)
#=> ["a=1","b=2","c=3"]
更新:在 jq 1.5 发布后,walk/1 被添加为 jq 定义的内置。它可以与上面定义的 kv 一起使用,例如如下:
walk(if type == "object" then kv else . end)
使用上述输入,结果将是:
[["a=1"],[[["b=2","c=3"]]]]
要“展平”输出,可以使用 flatten/0。这是一个完整的例子:
jq -cr 'def kv: to_entries | map("\(.key)=\(.value)");
walk(if type == "object" then kv else . end) | flatten[]'
输入:
[ "a":1, [["b":2, "c": 3]] ]
输出:
a=1
b=2
c=3
【讨论】:
【参考方案3】:顺便说一句,以@aioobe 的出色回答为基础。如果您需要键全部为大写,您可以使用ascii_upcase
通过修改他的示例来做到这一点:
jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
示例
我有一个与你类似的场景,但想在创建用于访问 AWS 的环境变量时将所有键都大写。
$ okta-credential_process arn:aws:iam::1234567890123:role/myRole | \
jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'
EXPIRATION=2019-08-30T16:46:55.307014Z
VERSION=1
SESSIONTOKEN=ABcdEFghIJ....
ACCESSKEYID=ABCDEFGHIJ.....
SECRETACCESSKEY=AbCdEfGhI.....
参考文献
https://github.com/oktadeveloper/okta-aws-cli-assume-role https://github.com/stedolan/jq/issues/492【讨论】:
【参考方案4】:没有jq
,我可以使用grep
和sed
导出json 中的每个项目,但这仅适用于我们有键/值对的简单情况
for keyval in $(grep -E '": [^\]' fileName.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
echo "$keyval"
done
这是一个示例响应:
❯ for keyval in $(grep -E '": [^\]' config.dev.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
echo "$keyval"
done
"env"="dev"
"memory"=128
"role"=""
"region"="us-east-1"
【讨论】:
以上是关于如何在 jq 中将 JSON 对象转换为 key=value 格式?的主要内容,如果未能解决你的问题,请参考以下文章