bash 如何在 jq 中将 JSON 对象转换为 key=value 格式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25378013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:10:33  来源:igfitidea点击:

How to convert a JSON object to key=value format in jq?

jsonbashjq

提问by gianebao

In jq, how can I convert a JSON to a string with key=value?

在 jq 中,如何将 JSON 转换为字符串key=value

From:

从:

{
    "var": 1,
    "foo": "bar",
    "x": "test"
}

To:

到:

var=1
foo=bar
x=test

回答by aioobe

You could try:

你可以试试:

jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' test.json

Here's a demo:

这是一个演示:

$ 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

回答by peak

Is there any way i can do this recursively?

有什么办法可以递归地做到这一点吗?

Here is a function which might do what you want:

这是一个可以执行您想要的功能的函数:

# 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;

Example: emit key=value pairs

示例:发出键=值对

def kv: to_entries | map("\(.key)=\(.value)");


[ {"a":1}, [[{"b":2, "c": 3}]] ] | recursively_reduce(kv)
#=> ["a=1","b=2","c=3"]

UPDATE: After the release of jq 1.5, walk/1 was added as a jq-defined built-in. It can be used with the above-defined kv, e.g. as follows:

更新:在 jq 1.5 发布后,walk/1 被添加为 jq 定义的内置函数。它可以与上面定义的 kv 一起使用,例如如下:

 walk(if type == "object" then kv else . end) 

With the above input, the result would be:

使用上述输入,结果将是:

[["a=1"],[[["b=2","c=3"]]]]

[["a=1"],[[["b=2","c=3"]]]]

To "flatten" the output, flatten/0 can be used. Here is a complete example:

要“展平”输出,可以使用 flatten/0。这是一个完整的例子:

jq -cr 'def kv: to_entries | map("\(.key)=\(.value)");
        walk(if type == "object" then kv else . end) | flatten[]'

Input:

输入:

[ {"a":1}, [[{"b":2, "c": 3}]] ]

Output:

输出:

a=1
b=2
c=3

回答by slm

Incidentally, building off of @aioobe's excellent answer. If you need the keys to be all upper case you can use ascii_upcaseto do this by modifying his example:

顺便说一句,建立在@aioobe 的出色回答之上。如果你需要所有的键都是大写,你可以ascii_upcase通过修改他的例子来做到这一点:

jq -r 'to_entries|map("\(.key|ascii_upcase)=\(.value|tostring)")|.[]'

Example

例子

I had a scenario similar to yours but wanted to uppercase all the keys when creating environment variables for accessing AWS.

我有一个与您类似的场景,但想在创建用于访问 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.....

References

参考

回答by Muhammad Soliman

without jq, I was able to export every item in json using grepand sedbut this will work for simple cases only where we have key/value pairs

没有jq,我能够使用grep和导出 json 中的每个项目,sed但这仅适用于我们有键/值对的简单情况

for keyval in $(grep -E '": [^\{]' fileName.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "$keyval"
done

here's a sample response:

这是一个示例响应:

? 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"