jq는 "빈" 값만 필터링합니다.

jq는 "빈" 값만 필터링합니다.

AWS CloudWatch 로그 페이로드(CLI 명령에서 생성됨)가 포함된 json 파일이 있습니다. jq를 사용하려고합니다.오직"retentionInDays" 필드가 없는 항목의 값을 반환합니다. 다음이 있고 내가 원하는 방식으로 모든 것을 반환하지만,tentionInDays가 있는 결과를 필터링할 수 없는 것 같습니다.

# Working output (unfiltered)
jq ".logGroups[] | { log_name: .logGroupName, log_arn: .arn, retention_scheme: .retentionInDays }" cwlogs.json

몇 가지를 시도했지만 오류가 발생하거나 아무것도 출력하지 않고 완료됩니다.

# Doesn't return anything
jq '.logGroups[] | { log_name: .logGroupName, log_arn: .arn, retention_scheme: select(.retentionInDays | contains ("null")?) }' cwlogs.json

# Errors with "jq: error (at cwlogs.json:760): number (7) and string ("null") cannot have their containment checked"
jq '.logGroups[] | { log_name: .logGroupName, log_arn: .arn, retention_scheme: select(.retentionInDays | contains ("null")) }' cwlogs.json

# Hangs forever
jq '.logGroups[] | select(.retentionInDays != "null").type' 

업데이트: 내가 사용하고 있는 JSON의 테스트 가능한 부분

{
    "logGroups": [
        {
            "storedBytes": 0,
            "metricFilterCount": 0,
            "creationTime": 1234,
            "logGroupName": "/aws/elasticbeanstalk/docker",
            "retentionInDays": 7,
            "arn": "longarnhere"
        },
        {
            "storedBytes": 0,
            "metricFilterCount": 0,
            "creationTime": 1245,
            "logGroupName": "/aws/elasticbeanstalk/nginx",
            "arn": "longarnhere"
        }
    ]
}

답변1

나는 당신 이 키가 logGroups전혀 없는 항목을 얻고 싶다고 가정합니다 .retentionInDays

$ jq '.logGroups[] | select( has("retentionInDays") == false )' file.json
{
  "storedBytes": 0,
  "metricFilterCount": 0,
  "creationTime": 1245,
  "logGroupName": "/aws/elasticbeanstalk/nginx",
  "arn": "longarnhere"
}

다음 세트를 원하는 경우(가능한 경우 두 개 이상이 있을 수 있음):

$ jq '.logGroups | map(select( has("retentionInDays") == false ))' file.json
[
  {
    "storedBytes": 0,
    "metricFilterCount": 0,
    "creationTime": 1245,
    "logGroupName": "/aws/elasticbeanstalk/nginx",
    "arn": "longarnhere"
  }
]

has("retentionInDays") | not대신 사용할 수도 있습니다 has("retentionInDays") == false.

답변2

대체 연산자를 사용할 수 있습니다: //.

예를 들어:

echo '{"a" : "b"}' | jq '. | .c // "Null"'

type또는 귀하의 예에서는 필터에 다음을 추가하여 필터링을 수행할 수 있습니다.

jq '.logGroups[] | select (.retentionInDays.type != null)' 

관련 정보