json 如何将对象映射到数组以便将其转换为 csv?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20181467/
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-03 20:04:32  来源:igfitidea点击:

How to map an object to arrays so it can be converted to csv?

jsonjq

提问by Louis

I'm trying to convert an object that looks like this:

我正在尝试转换一个看起来像这样的对象:

{
  "123" : "abc",
  "231" : "dbh",
  "452" : "xyz"
}

To csv that looks like this:

对于看起来像这样的 csv:

"123","abc"
"231","dbh"
"452","xyz"

I would prefer to use the command line tool jqbut can't seem to figure out how to do the assignment. I managed to get the keys with jq '. | keys' test.jsonbut couldn't figure out what to do next.

我更喜欢使用命令行工具jq但似乎无法弄清楚如何进行分配。我设法拿到了钥匙,jq '. | keys' test.json但不知道下一步该怎么做。

The problem is you can't convert a k:v object like this straight into csv with @csv. It needs to be an array so we need to convert to an array first. If the keys were named, it would be simple but they're dynamic so its not so easy.

问题是你不能像这样直接将 ak:v 对象转换成带有 .csv 的 .csv 文件@csv。它需要是一个数组,所以我们需要先转换为一个数组。如果键被命名,它会很简单,但它们是动态的,所以它不是那么容易。

回答by Jeff Mercado

Try this filter:

试试这个过滤器:

to_entries[] | [.key, .value]
  • to_entriesconverts an object to an array of key/value objects. []breaks up the array to each of the items in the array
  • then for each of the items, covert to an array containing the key and value.
  • to_entries将对象转换为键/值对象数组。 []将数组分解为数组中的每个项目
  • 然后对于每个项目,转换为包含键和值的数组。

This produces the following output:

这会产生以下输出:

[
  "123",
  "abc"
],
[
  "231",
  "dbh"
],
[
  "452",
  "xyz"
]

Then you can use the @csvfilter to convert the rows to CSV rows.

然后您可以使用@csv过滤器将行转换为 CSV 行。

$ echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries[] | [.key, .value] | @csv'
"123","abc"
"231","dbh"
"452","xyz"

回答by Jón Tómas

Here's an example I ended up using this morning (processing PagerDuty alerts):

这是我今天早上最终使用的示例(处理 PagerDuty 警报):

cat /tmp/summary.json | jq -r '
  .incidents
  | map({desc: .trigger_summary_data.description, id:.id})
  | group_by(.desc)
  | map(length as $len
  | {desc:.[0].desc, length: $len}) 
  | sort_by(.length) 
  | map([.desc, .length] | @csv)
  | join("\n") '

This dumps a CVS-separated document that looks something like: "[Triggered] Something annoyingly frequent",31 "[Triggered] Even more frequent alert!",35 "[No data] Stats Server is probably acting up",55

这会转储一个 CVS 分隔的文档,看起来像: "[Triggered] Something annoyingly frequent",31 "[Triggered] Even more frequent alert!",35 "[No data] Stats Server is probably acting up",55

回答by tomsoft

Jeff answer is a good starting point, something closer to what you expect:

杰夫的回答是一个很好的起点,更接近您的期望:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))'

[
 "123,abc",
 "231,dbh",
 "452,xyz"
]

But did not find a way to join using newline:

但是没有找到使用换行符加入的方法:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))|join("\n")'

"123,abc\n231,dbh\n452,xyz"

回答by Sunil shakya

Try This give same output you want

试试这给出你想要的相同输出

echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries | .[] | "\"" + .key + "\",\"" + (.value | tostring)+ "\""'

回答by kjetildm

onecol2txt () {
 awk 'BEGIN { RS="_end_"; FS="\n"}
   { for (i=2; i <= NF; i++){
       printf "%s ",$i 
       }
     printf "\n" 
   }'
}
cat jsonfile | jq -r -c '....,"_end_"' | onecol2txt