jq - 조건부로 한 값을 다른 값으로 설정

jq - 조건부로 한 값을 다른 값으로 설정

존재하는 값에 따라 json 문서의 필드 값을 세 가지 값 중 하나로 설정하려면 jq를 사용해야 합니다. 이론적으로 이것은 다음과 같습니다: 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"
}

필드를 만들고 해당 값을 null 또는 null 이외의 값으로 설정하고 싶습니다 Severity. abc_severitynull이거나 비어 있으면 로 설정하고 def_severity, null이거나 비어 있으면 로 설정하고 싶습니다 ghi_severity. 세 개가 모두 null이거나 비어 있으면 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?대신 빈 문자열을 제공합니다 . 또한 물음표는 대략 " 이 키가 존재하지 않으면 대체"를 의미합니다. 예시에서는 세 개의 키가 모두 존재하지만 해당 값은 .nullfalsenullnull

nullnull 값을 계속 사용하면 jq표현식은 다음과 같습니다.

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

위의 표현식은 3개의 값 중 가 아닌 첫 번째 값을 선택하고 null, 가장 왼쪽의 값을 먼저 테스트한 후 오른쪽으로 이동하거나, null모두 이면 입니다 null. 하지만 지금은 빈 문자열을 처리해야 하기 때문에 작동하지 않습니다.마치그들은 null.

도우미 함수를 도입하여 (타이핑을 줄이기 위해) 이 작업을 수행할 수 있습니다.

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

문자열이 비어 있지 않으면 도우미 함수는 n문자열을 있는 그대로 반환하고, 그렇지 않으면 를 반환합니다 null. 체인 연산자의 경우 ( 피벗할 때) //가 아닌 세 값 중 첫 번째 값을 선택하거나 , 세 값이 모두 인 경우 빈 문자열을 선택합니다 .nullnnull

데이터를 사용하여 명령줄에서 위 내용을 테스트합니다.

$ 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"
}

관련 정보