在 shell 上将文本文件转换为 CSV

jot*_*ken 4 command-line csv text-processing json

我想将文本文件转换为 CSV 格式。

以下是该文件的摘录:

{"Outdated":false,"Watt":233,"Timestamp":1669647142,"A_Plus":6523.896,"A_Plus_HT":4494.82,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":235,"Timestamp":1669647152,"A_Plus":6523.896,"A_Plus_HT":4494.82,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":235,"Timestamp":1669647596,"A_Plus":6523.896,"A_Plus_HT":4494.82,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":233,"Timestamp":1669651191,"A_Plus":6524.496,"A_Plus_HT":4495.42,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":276,"Timestamp":1669654797,"A_Plus":6524.816,"A_Plus_HT":4495.74,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":437,"Timestamp":1669658393,"A_Plus":6525.901,"A_Plus_HT":4496.825,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":362,"Timestamp":1669661992,"A_Plus":6526.732,"A_Plus_HT":4497.656,"A_Plus_NT":2029.076,"A_Minus":8841.63}
{"Outdated":false,"Watt":471,"Timestamp":1669665603,"A_Plus":6527.062,"A_Plus_HT":4497.986,"A_Plus_NT":2029.076,"A_Minus":8841.63}
Run Code Online (Sandbox Code Playgroud)

该结构类似于 JSON 文件,但不幸的是结构并不完全匹配。我已经使用过这个工具(https://github.com/alingse/jsoncsv),但不幸的是,由于结构错误,我收到了错误消息。

如何将其转换为 CSV 文件?

感谢您的帮助!

ste*_*ver 9

输入的每一行都是一个有效的 JSON 对象 - 因此,如果您不关心 CSV 标头,您可以简单地将它们解构回数组并通过过滤器传递它们@csv

$ jq -r '[.[]] | @csv' file
false,233,1669647142,6523.896,4494.82,2029.076,8841.63
false,235,1669647152,6523.896,4494.82,2029.076,8841.63
false,235,1669647596,6523.896,4494.82,2029.076,8841.63
false,233,1669651191,6524.496,4495.42,2029.076,8841.63
false,276,1669654797,6524.816,4495.74,2029.076,8841.63
false,437,1669658393,6525.901,4496.825,2029.076,8841.63
false,362,1669661992,6526.732,4497.656,2029.076,8841.63
false,471,1669665603,6527.062,4497.986,2029.076,8841.63
Run Code Online (Sandbox Code Playgroud)

如果您确实关心标头,那就更复杂了。我能想到的最好的办法是:

  • 整个文件放入索引行数组中
  • 执行行数组的缩减,使用从第 0元素提取的键对其进行初始化

您现在有一个数组的数组,顶部有一个标头数组,它可以映射回 CSV 数组(最后映射到各个 CSV 行):

$ jq -r --slurp 'to_entries |
    reduce . as $row ([.[0] | .value | keys_unsorted]; . + [$row[] | .value | to_entries | map(.value)]) |
    map(@csv) | .[]
  ' file
"Outdated","Watt","Timestamp","A_Plus","A_Plus_HT","A_Plus_NT","A_Minus"
false,233,1669647142,6523.896,4494.82,2029.076,8841.63
false,235,1669647152,6523.896,4494.82,2029.076,8841.63
false,235,1669647596,6523.896,4494.82,2029.076,8841.63
false,233,1669651191,6524.496,4495.42,2029.076,8841.63
false,276,1669654797,6524.816,4495.74,2029.076,8841.63
false,437,1669658393,6525.901,4496.825,2029.076,8841.63
false,362,1669661992,6526.732,4497.656,2029.076,8841.63
false,471,1669665603,6527.062,4497.986,2029.076,8841.63
Run Code Online (Sandbox Code Playgroud)


abo*_*uso 9

这是一种非常常用的数据格式,Json行

您可以使用Miller 6并运行

mlrgo --ijsonl --ocsv cat input.jsonl
Run Code Online (Sandbox Code Playgroud)

要得到

Outdated,Watt,Timestamp,A_Plus,A_Plus_HT,A_Plus_NT,A_Minus
false,233,1669647142,6523.896,4494.82,2029.076,8841.63
false,235,1669647152,6523.896,4494.82,2029.076,8841.63
false,235,1669647596,6523.896,4494.82,2029.076,8841.63
false,233,1669651191,6524.496,4495.42,2029.076,8841.63
false,276,1669654797,6524.816,4495.74,2029.076,8841.63
false,437,1669658393,6525.901,4496.825,2029.076,8841.63
false,362,1669661992,6526.732,4497.656,2029.076,8841.63
false,471,1669665603,6527.062,4497.986,2029.076,8841.63
Run Code Online (Sandbox Code Playgroud)

在下面的有用评论中,有一个关于 Miller 5 中的实现方法的注释:

mlr --ijson --ocsv cat input >output
Run Code Online (Sandbox Code Playgroud)


pLu*_*umo 8

json对我来说,首先转换为适当的,然后使用解析器(例如jqjsoncsv您已经尝试过的)而不是编写自己的解析器似乎更容易和更安全。

只需添加[第一行并在]最后一行之后附加一个逗号即可转换为 json,除了最后一行之外。

sed '1s/^/[/;$!s/$/,/;$a]' file
Run Code Online (Sandbox Code Playgroud)

然后转换为csv使用jq

jq -r '(.[0] | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv'
Run Code Online (Sandbox Code Playgroud)

并将其放在一起:

$ sed '1s/^/[/;$!s/$/,/;$a]' file | jq -r '(.[0] | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv'
"Outdated","Watt","Timestamp","A_Plus","A_Plus_HT","A_Plus_NT","A_Minus"
false,233,1669647142,6523.896,4494.82,2029.076,8841.63
false,235,1669647152,6523.896,4494.82,2029.076,8841.63
false,235,1669647596,6523.896,4494.82,2029.076,8841.63
false,233,1669651191,6524.496,4495.42,2029.076,8841.63
false,276,1669654797,6524.816,4495.74,2029.076,8841.63
false,437,1669658393,6525.901,4496.825,2029.076,8841.63
false,362,1669661992,6526.732,4497.656,2029.076,8841.63
false,471,1669665603,6527.062,4497.986,2029.076,8841.63
Run Code Online (Sandbox Code Playgroud)