使用 JQ 展平嵌套的 Json 对象

mil*_*erf 2 json flatten jq keypaths

我正在创建一个脚本来将 JSON 对象转换为“字符串”文件(用于翻译目的)。这个想法是要转变:

{
   "TRANSLATION1": "text1",
   "TRANSLATION2": "text2"
}
Run Code Online (Sandbox Code Playgroud)

进入

"TRANSLATION1" = "text1";
"TRANSLATION2" = "text2";
Run Code Online (Sandbox Code Playgroud)

这是用以下方法完成的: jq -r 'to_entries|map("\"\(.key)\"=\(.value|tojson);")|.[]'

好的!

现在,我的问题是嵌套对象:

{
   "TRANSLATION1": "text1",
   "TRANSLATION2": "text2",
   "TRANSLATION3": {
     "SUBTRANS1": "subtranslation1",
     "SUBTRANS2": "subtranslation2",
   }
}
Run Code Online (Sandbox Code Playgroud)

我想要的结果是:

"TRANSLATION1" = "text1";
"TRANSLATION2" = "text2";
"TRANSLATION3.SUBTRANS1" = "subtranslation1";
"TRANSLATION3.SUBTRANS2" = "subtranslation2";
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?我已经挠头好几个小时了......

pea*_*eak 5

一种方法是使用tostream

tostream
| select(length==2)
| (.[0] | join(".")) as $k
| .[1] as $v
| "\"\($k)\" = \"\($v)\";"
Run Code Online (Sandbox Code Playgroud)

当与 -r 命令行选项一起使用时,假设输入是有效的 JSON,这将产生所需的结果。

检查关键假设[*]

可能值得明确的是,如果任何键名称包含句点,则输出格式可能不是很有用,因此可能值得检查是否确实如此,例如如下所示:

[.. | objects | keys_unsorted[]]
| map(select(index(".")))
| unique[]
Run Code Online (Sandbox Code Playgroud)

如果你的jq没有tostream

paths as $path
| getpath($path) 
| strings
| "\"\($path|join("."))\" = \"\(.)\";"
Run Code Online (Sandbox Code Playgroud)

[*] 双关语