我有一个json文件,格式如下:
{"key1": "value1"}
{"key2": "value2"}
{"key3": "value3"}
我想把这个json转换成csv。但是,文件中所有对象中的关键点并不相同。我有一个所有可能的键的列表,但其中一些可能在任何json对象中都丢失了。因此,如果是这种情况,我只想为该列插入一个null值。
如何将以这种方式格式化的json文件转换为我想要的csv?
更新:下面是一个名为objects.json 的示例文件
{"key1": "value1", "key2": "value2"}
{"key1": "value3", "key2": "value4", "key3": "value5"}
{"key1": "value6", "key2": "value7", "key4": "value8"}
每个对象都在文件的新行上。
我有一个名为allkeys.json的json文件,其中有一个对象,包含所有可能的空值键:
{"key1": null, "key2": null, "key3": null, "key4": null}
我想将example.json转换为一个包含所有列的CSV文件,并且对于任何缺少列的对象,都会有null值。
所以我想要的输出是:
key1,key2,key3,key4
value1,value2,,
value3,value4,value5,
value6,value7,,value8
您需要读取文件中的所有数据,以确定哪些键集对所有对象都是公共的,然后输出那些键和值(如果对象包含它们(。在这个过程中,最容易混淆数据。
$ jq -sr '([.[] | keys[]] | unique) as $keys | $keys, (.[] | [.[$keys[]]]) | @csv' input.json
"key1","key2","key3"
"value1",,
,"value2",
,,"value3"
jqplay
我有一个所有可能的密钥的列表
让我们假设这个列表可以作为字符串的JSON数组,例如$keys。然后使用以下jq过滤器有几个优点,包括效率(不使用-s选项(和不丢失数据(相对于$keys(:
$keys, (inputs | [.[$keys[]]]) | @csv
示例用法:
< input.json jq -nr --argjson keys '["key1","key2","key3","key4"]' -f program.jq
输出
"key1","key2","key3","key4"
"value1",,,
,"value2",,
,,"value3",
双通道解决方案
如果密钥必须从数据中推断出来,则可能仍然值得考虑两次通过的解决方案,因为这将避免"错误";"诋毁";数据。在任何情况下,如果采用两遍解决方案,上述解决方案可以用于第二部分,第一部分如下:
jq -nc 'reduce inputs as $x (null; . + $x) | keys_unsorted' input.json
因此,在类似bash的环境中,您将拥有:
<input.json jq -nr
--argjson keys "$(< input.json jq -nc 'reduce inputs as $x (null; . + $x) | keys_unsorted')" '
$keys, (inputs | [.[$keys[]]]) | @csv
'
如果正确理解了这个问题,您可以做的是创建一个所有键都设置为null的json文件,然后将其与缺少键的文件合并。然后,您将拥有一个包含所有密钥的新json文件,稍后可以像往常一样将其转换为csv。这可以使用jq
add
来完成,如本例所示:
echo '{"key1":null}{"key2":null}{"key3":null}{"key4":null}{"key5":null}' > allkeys.json
echo '{"key1":"value1"}{"key2":"value2"}{"key3":"value3"}' > update.json
jq -s add allkeys.json update.json
输出:
{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": null,
"key5": null
}
将转换添加到csv:
jq -s add allkeys.json update.json | jq -r '[.[]] | @csv'
输出:
"value1","value2","value3",,