将键=值对转换为JSON

时间:2020-05-14 10:10:59

标签: json jq

我正在尝试将包含键=值对的文件转换为JSON。 该文件可能包含Windows EOL(\r\n)和空行。

给出以下输入(注意空行):

foo = aa
bar = bb

qux = cc
white space = white space
* = special-char


这是预期的结果:

{
  "foo": "aa",
  "bar": "bb",
  "qux": "cc",
  "white space": "white space",
  "*": "special-char"
}

我设法走了这么远:

{
  "foo": "aa"
}
{
  "bar": "bb"
}
{
  "qux": "cc"
}
{
  "white space": "white space"
}
{
  "*": "special-char"
}

使用以下命令:

 jq --raw-input 'split("\n") | map(split(" = ") | { (.[0]): .[1] }) | .[]' 

但是我无法弄清丢失的部分。缺少什么,或者这是实现此目标的更好方法?

编辑:添加了有关空行和Windows EOL的约束

2 个答案:

答案 0 :(得分:3)

您真的很亲近。最后放下\r,除以=,将生成的数组转换为对象,将它们放入数组,然后将其传递到add

[ inputs
  | gsub("\r$"; "")
  | split(" = "; "")
  | select(length == 2)
  | {(.[0]): .[1]}
] | add

您需要在命令行上指定--raw-input / -R--null-input / -n选项才能使其正常工作。

答案 1 :(得分:1)

如果其中一个“值”包含“ =”,则天真使用split("=")会产生错误的结果。如果您的jq支持capture,那么可以使用以下解决方案来避免该问题:

jq -nR '
  def trim: sub("^ +";"") | sub(" +$";"");
  [inputs
   | select(index("="))
   | sub("\r$"; "")
   | capture( "(?<key>[^=]*)=(?<value>.*)" )
   | ( (.key |= trim) | (.value |= trim)) ]
  | from_entries'