JQ'select'还是'if'?

JQ 'select' or 'if'?

我有一个 JSON 文件:

{
  "StatusInfos": null,
  "ReadReplicaSourceDBInstanceIdentifier": null,
  "DBInstanceIdentifier": "test1"
}
{
  "StatusInfos": null,
  "ReadReplicaSourceDBInstanceIdentifier": null,
  "DBInstanceIdentifier": "test2"
}
{
  "StatusInfos": [
    {
      "Status": "replicating",
      "StatusType": "read replication",
      "Normal": true
    }
  ],
  "ReadReplicaSourceDBInstanceIdentifier": "test1",
  "DBInstanceIdentifier": "read-rep-test1"
}
{
  "StatusInfos": [
    {
      "Status": "replicating",
      "StatusType": "read replication",
      "Normal": true
    }
  ],
  "ReadReplicaSourceDBInstanceIdentifier": "test2",
  "DBInstanceIdentifier": "read-rep-test2"
}

我正在尝试制作:

{
  "StatusInfos": null,
  "ReadReplicaSourceDBInstanceIdentifier": null,
  "DBInstanceIdentifier": "test1"
}
{
  "StatusInfos": null,
  "ReadReplicaSourceDBInstanceIdentifier": null,
  "DBInstanceIdentifier": "test2"
}
{
  "RepStatus": "replicating",
  "RepStatusType": "read replication",
  "ReadReplicaSourceDBInstanceIdentifier": "test1",
  "DBInstanceIdentifier": "read-rep-test1"
}
{
  "RepStatus": "replicating",
  "RepStatusType": "read replication",
  "ReadReplicaSourceDBInstanceIdentifier": "test2",
  "DBInstanceIdentifier": "read-rep-test2"
}

我已经尝试了 'select' 和 'if' 的几十种变体,其中大部分只是简单地吐出错误。我最近的尝试(如果这很重要,我仅限于 jq 1.3)既没有产生错误也没有输出:

   cat json_file |
      jq -r '{ DBInstanceIdentifier,
               ReadReplicaSourceDBInstanceIdentifier
             } +
             ( select( .StatusType == "read replication" ) |
              .StatusInfos[] | { RepStatusType: .StatusType, RepStatus: .Status }
             )'

JQ对我来说真是莫名其妙。我多次参考了这些手册,但它们给出的是示例,而不是原则。所以除了如何解决我眼前的问题,如果你能推荐我如何真正理解 JQ,我将不胜感激。

一个 if 处理所有实体但保留 StatusInfos: null 完整的实体将如:

jq -r 'if .StatusInfos != null then {
    RepStatus: .StatusInfos[0].Status,
    RepStatusType: .StatusInfos[0].StatusType,
    ReadReplicaSourceDBInstanceIdentifier,
    DBInstanceIdentifier } else . end'

或者,当需要处理多个 StatusInfo 时:

jq -r 'if .StatusInfos != null then 
        .StatusInfos[] as $info | {
             RepStatus: $info.Status,
             RepStatusType: $info.StatusType,
             ReadReplicaSourceDBInstanceIdentifier,
             DBInstanceIdentifier }
    else . end'

试试这个:

reduce ((.StatusInfos//[])[] | select(.StatusType == "read replication")) as $info
    ({ ReadReplicaSourceDBInstanceIdentifier, DBInstanceIdentifier };
    .RepStatus = $info.Status | .RepStatusType = $info.StatusType)

如果您可以访问更新版本的 jq,则可以使用错误忽略过滤器将 (.StatusInfos//[])[] 更改为 .StatusInfos?[]?

这是一个变体,如果可能,它用最后一个数组元素的属性替换 StatusInfos

if .StatusInfos == null
then .
else .RepStatus     = .StatusInfos[-1].Status
   | .RepStatusType = .StatusInfos[-1].StatusType
   | del(.StatusInfos)
end