让 JQ 将对象数组转换为字符串

Make JQ transform an array of objects to a string

我有一个 JSON 文件:

{
  "ClassIdentifier": "consumer-leads",
  "StateMode": "txt-2300",
  "StateGroups": []
}
{
  "ClassIdentifier": "main",
  "StateMode": null,
  "StateGroups": [
    {
      "Status": "active",
      "StateGroupName": "default"
    },
    {
      "Status": "active",
      "StateGroupName": "brown-space"
    },
    {
      "Status": "active",
      "StateGroupName": "txt-hosts"
    }
  ]
}
{
  "ClassIdentifier": "paid-media",
  "StateMode": "txt-2300",
  "StateGroups": []
}
{
  "ClassIdentifier": "reports",
  "StateMode": null,
  "StateGroups": [
    {
      "Status": "active",
      "StateGroupName": "txt-hosts"
    },
    {
      "Status": "active",
      "StateGroupName": "grey-space"
    },
    {
      "Status": "active",
      "StateGroupName": "default"
    }
  ]
}

我需要的输出:

consumer-leads,txt-2300,null
main,null,brown-space|default|txt-hosts
paid-media,txt-2300,null
reports,null,default|grey-space|txt-hosts

请注意,StateGroup(如果存在的话)按 StateGroupName 排序,因为(或之前)它们被转换为由竖线分隔的值字符串。

我的尝试给了我部分结果,但没有真正起到作用:

cat json_file |
      jq -r '[ .ClassIdentifier,
               .StateMode,
               .StateGroups[]
             ]'

cat json_file |
      jq -r '{ ClassIdentifier,
               StateMode
             } +
             ( .StateGroups[] | { StateGroupName,  Status } )
             '

cat json_file |
      jq -r ' [ .ClassIdentifier,
              .StateMode,
              .StateGroups |= sort_by( .StateGroupName )
             ]'

更新:我们必须使用 JQ 1.3,所以请在回复时记住这一点。

这应该有效:

[
    .ClassIdentifier,
    .StateMode // "null",
    (.StateGroups
        | map(select(.Status=="active").StateGroupName)
        | sort
        | join("|")
        | if .=="" then "null" else . end
    )
] | @csv

产生:

"consumer-leads","txt-2300","null"
"main","null","brown-space|default|txt-hosts"
"paid-media","txt-2300","null"
"reports","null","default|grey-space|txt-hosts"

请注意,由于您使用的是 1.3,join/1 将无法使用。不过自己实现应该不难。

def join(sep): sep as $sep
    | reduce .[1:][] as $item (.[0]|tostring; . + $sep + $item)
    ;