我需要使用 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"
}