jq - 有條件地將一個值設置為另一個值
我需要使用 jq 將 json doc 中的欄位值設置為三個值之一,具體取決於哪個存在。名義上,這看起來像:
set X to (if A exists, else if B exists, else if C exists, else "")
.我有一個範例 json doc,如下所示:
{ "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
也始終是。""
我確定我在這裡忽略了一些簡單的東西,我似乎無法理解。
空字元串仍然是字元串,因此
.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" }