43

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

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

对于看起来像这样的 csv:

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

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

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

4

5 回答 5

67

试试这个过滤器:

to_entries[] | [.key, .value]
  • to_entries将对象转换为键/值对象数组。 []将数组分解为数组中的每个项目
  • 然后对于每个项目,转换为包含键和值的数组。

这会产生以下输出:

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

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

$ echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries[] | [.key, .value] | @csv'
"123","abc"
"231","dbh"
"452","xyz"
于 2014-06-17T01:11:18.660 回答
5

这是我今天早上最终使用的一个示例(处理 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") '

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

于 2015-02-27T18:51:28.150 回答
4

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

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

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

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

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

"123,abc\n231,dbh\n452,xyz"
于 2014-11-06T09:24:32.393 回答
1

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

echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries | .[] | "\"" + .key + "\",\"" + (.value | tostring)+ "\""'
于 2018-05-15T11:15:52.947 回答
-3
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
于 2015-06-19T12:41:28.243 回答