【问题标题】:Can't put JSON output into CSV format with jq无法使用 jq 将 JSON 输出转换为 CSV 格式
【发布时间】:2019-05-14 05:56:28
【问题描述】:

我正在构建 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 格式?

【问题讨论】:

    标签: json csv jq flatten


    【解决方案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(",")'
    

    【讨论】:

      【解决方案2】:

      accepted Answer 解决了另一个不起眼的 jq 错误:

      字符串 ("xxx") 不能是 csv 格式,只能是数组

      在我的情况下,我不想打印 jq 的 整个 输出,而是打印我提供给 jq 的每个 Elastic Search document作为单独一行的 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-19
        • 1970-01-01
        • 2019-05-01
        • 1970-01-01
        • 2015-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多