无法使用jq将JSON输出转换为CSV格式

时间:2018-12-13 03:39:53

标签: json csv jq flatten

我正在构建一个AWS EBS卷属性列表,因此我可以使用jq将其作为CSV存储在变量中。我将把变量输出到电子表格。

第一个命令使用jq给出我要寻找的值:

aws ec2 describe-volumes | jq -r '.Volumes[] | .VolumeId, .AvailabilityZone, .Attachments[].InstanceId, .Attachments[].State, (.Tags // [] | from_entries.Name)'

给出我想要的输出:

MIAPRBcdm0002_test_instance
vol-0105a1678373ae440
us-east-1c
i-0403bef9c0f6062e6
attached
MIAPRBcdwb00000_app1_vpc
vol-0d6048ec6b2b6f1a4
us-east-1c
MIAPRBcdwb00001 /carbon
vol-0cfcc6e164d91f42f
us-east-1c
i-0403bef9c0f6062e6
attached

但是,如果我将其放入CSV格式以便可以将变量输出到电子表格,则该命令会炸毁并且不起作用:

aws ec2 describe-volumes | jq -r '.Volumes[] | .VolumeId, .AvailabilityZone, .Attachments[].InstanceId, .Attachments[].State, (.Tags // [] | from_entries.Name)| @csv'
jq: error (at <stdin>:4418): string ("vol-743d1234") cannot be csv-formatted, only array

对于EBS卷,即使将JSON的顶级转换为CSV格式也失败:

aws ec2 describe-volumes | jq -r '.Volumes[].VolumeId | @csv'
jq: error (at <stdin>:4418): string ("vol-743d1234") cannot be csv-formatted, only array

这是我正在使用这些命令的AWS EBS Volumes JSON FILE(该文件已清除公司标识符,但是有效的json)。

如何使用jq将json转换为CSV格式?

2 个答案:

答案 0 :(得分:1)

您只能将@csv应用于数组内容,只需将过滤器封装在[..]中,如下所示

jq -r '[.Volumes[] | .VolumeId, .AvailabilityZone, .Attachments[].InstanceId, .Attachments[].State, (.Tags // [] | from_entries.Name)]|@csv'

使用上述内容可能仍会保留引号,因此在此处使用join()也是合适的

jq -r '[.Volumes[] | .VolumeId, .AvailabilityZone, .Attachments[].InstanceId, .Attachments[].State, (.Tags // [] | from_entries.Name)] | join(",")'

答案 1 :(得分:0)

accepted Answer解决了另一个模糊的jq错误:

字符串(“ xxx”)不能采用csv格式,只能是数组

在我的情况下,我不希望jq的 整个 输出,而是希望打印我提供给jq的每个Elastic Search 文档作为一行上的CSV字符串。为此,我只需 移动括号以仅封装每行要包含的项目

首先,通过将方括号仅放在每行输出中要包含的项目周围,我制作了:

jq -r '.hits.hits[]._source | [.syscheck.path, .syscheck.size_after]'
[
  "/etc/group-",
  "783"
]
[
  "/etc/gshadow-",
  "640"
]
[
  "/etc/group",
  "795"
]
[
  "/etc/gshadow",
  "652"
]
[
  "/etc/ssh/sshd_config",
  "3940"
]

将其输到| @csv会在每行上用引号和逗号分隔打印每个文档的.syscheck.path和.syscheck.size_after值:

$ jq -r '.hits.hits[]._source | [.syscheck.path, .syscheck.size_after] | @csv'
"/etc/group-","783"
"/etc/gshadow-","640"
"/etc/group","795"
"/etc/gshadow","652"
"/etc/ssh/sshd_config","3940"

或按照接受的答案中指出的模式省略引号:

$ jq -r '.hits.hits[]._source | [.syscheck.path, .syscheck.size_after] | join(",")'
/etc/group-,783
/etc/gshadow-,640
/etc/group,795
/etc/gshadow,652
/etc/ssh/sshd_config,3940