jq - 有条件地将一个值设置为另一个值

jq - 有条件地将一个值设置为另一个值

我需要使用 jq 将 json 文档中的字段值设置为三个值之一,具体取决于哪个值存在。理论上这看起来像:set X to (if A exists, else if B exists, else if C exists, else "")

我的 json 文档示例如下所示:

{
  "name": "0230",
  "publish_date": "2007-08-18",
  "abc_severity": "",
  "def_severity": "medium",
  "ghi_severity": "negligible"
}

我想创建一个字段并将其值设置为非空或空Severity的值。abc_severity如果它为 null 或空,我想将其设置为def_severity,如果它为 null 或空,我想将其设置为ghi_severity。如果所有三个都为 null 或为空,则可以使用空值创建""。所以这种情况下的输出将是:

{
  "name": "0230",
  "publish_date": "2007-08-18",
  "abc_severity": "",
  "def_severity": "medium",
  "ghi_severity": "negligible",
  "Severity": "medium"
}

以下是我似乎能够得到的最接近的:

'. | if .abc_severity? then .Severity=.abc_severity else if .def_severity? then .Severity=.def_severity else if .ghi_severity? then .Severity=.ghi_severity else .Severity="" end end end'

但即使存在一个或多个其他值,的值也Severity始终为。""我确信我在这里忽略了一些简单的东西,我似乎无法理解它。

答案1

空字符串仍然是字符串,因此.abc_severity?会给您一个空字符串,而不是null(或false)。另请注意,问号大约意味着“null如果该密钥不存在则替换为”。在示例中,所有三个键都存在,但它们的值不是null

如果您一直使用null空值,您的jq表达式将类似于

.Severity = (.abc_severity // .def_severity // .ghi_severity )

上面的表达式会选择三个不是 的值中的第一个null,先测试最左边的值然后向右,或者null如果它们全部都是null。但这现在行不通了,因为我们必须处理空字符串仿佛他们是null

我们可以通过引入一个辅助函数来做到这一点(以减少我们的输入):

def n: if . == "" then null else . end;
.Severity = ((.abc_severity|n) // (.def_severity|n) // (.ghi_severity|n) // "")

如果字符串不为空,我们的辅助函数n将按原样返回字符串;否则,它返回null。对于链式//运算符,我们选择三个值中第一个不是 的值(null当透视时)n,或者如果所有三个值都是 则选择空字符串null

使用您的数据在命令行上测试上述内容:

$ jq 'def n: if . == "" then null else . end; .Severity = ((.abc_severity|n) // (.def_severity|n) // (.ghi_severity|n) // "")' file
{
  "name": "0230",
  "publish_date": "2007-08-18",
  "abc_severity": "",
  "def_severity": "medium",
  "ghi_severity": "negligible",
  "Severity": "medium"
}

相关内容