2016-09-14 5 views
2

jq를 사용하여 json 객체에서 null 값을 제거하려고합니다. 나는 그들의 github에 this issue을 발견했다. 그래서 지금 나는 del와 그들을 삭제하려고 노력하고있다.null 값 모두 제거

'{ id: $customerId, name, phones: ([{ original: .phone }, 
{ original: .otherPhone}]), email} | del(. | nulls)' 

이 아무것도하지 않는 것 : 나는이 있습니다. 그러나 nulls.phones으로 바꾸면 전화 번호가 삭제됩니다. del/1 할 수있는, 그런데

. as $o | [paths[] | {(.) : ($o[.])} ] | add 

다음

jq -n '{"a":1, "b": null, "c": null} | with_entries(select(.value != null))' 
{ 
    "a": 1 
} 

또는 paths/0과 같이 사용할 수 있습니다

+1

충분히 길게 작성하십시오. 실행, 입력, 실제 출력 및 원하는 출력을 보여줍니다. (예를 들어, 당신은 hereoc에서 최소한의 JSON 입력을 제공 할 수 있습니다. 'jq'... your code here ... '<<'EOF '를 실행하십시오. 여기에는 문제를 설명하는 JSON과'EOF ' 나중에). [Minimal, Complete, Verifiable Examples에 대한 도움말 센터 문서] (http://stackoverflow.com/help/mcve)도 참조하십시오. –

+0

... 그대로, 데이터 구조에서 실제로 NUL이 어디에 있는지 알기가 어렵습니다. 이는 솔루션을 빌드하거나 테스트 할 수있는 중요한 요소입니다. –

+0

현재 질문을 끝내기 위해 투표를하는 동안 (1) 다른 사람들이 동의하지 않는 한 실제로 닫히지 않을 것입니다. (2) 닫힌 질문을 편집하면 다시 열기를 위해 대기열에 자동으로 넣습니다. 따라서 MCVE를 포함하도록 확장하면 클로저가 반전되어야합니다. –

답변

3

다음은 JSON 객체에서 모든 널 (null) 값 키를 제거하는 방법을 보여줍니다 또한 같은 결과를 얻기 위해 사용된다. 분명히

reduce keys[] as $k (.; if .[$k] == null then del(.[$k]) else . end) 

또는 덜하지만, 더 간결 :이 필터를 사용하여

del(.[ (keys - [paths[]])[] ]) 

을 그리고 기록을 위해, 여기 delpaths/1를 사용하는 방법은 두 가지입니다 :

jq -n '{"a":1, "b": null, "c": null, "d":2} as $o 
    | $o 
    | delpaths([ keys[] | select($o[.] == null) ] | map([.]))' 


$ jq -n '{"a":1, "b": null, "c": null, "d":2} 
    | [delpaths((keys - paths) | map([.])) ] | add' 

모두이 마지막으로는 두 경우 출력은 동일합니다. { "a": 1, "d": 2 }

+0

'del/1'과 같은 함수에 대한 참조에서'/ 1'이 의미하는 것은 무엇입니까?나는 다른 답변에서도 그것을 보았지만 jq의 문서에서는 그렇지 않다. –

+1

그것은 기능의 원동력입니다. 가장 최근 버전의 jq에는 내장 함수 FUNCTOR/ARITY – peak

2

이것은 del/1을위한 것이 아닙니다. 당신이 .phones 속성을 제거하고 싶다면 입력으로 대상을 감안할 때, 당신은 할 것 : 즉

del(.phones) 

del에 매개 변수는 제거 할 속성에 경로입니다.

이것을 사용하려면 모든 경로를 null 값으로 계산하여이를 전달해야합니다. 그것은 혼전의 더 많은 것 일 것입니다. 쉬운 접근을 위해


, 당신은 null 값을 찾기 위해 오브젝트 트리를 걸어해야합니다. 발견되면 해당 속성을 제거하거나 필터링하십시오. walk/1을 사용하면 필터를 재귀 적으로 적용하여 null 값을 제외 할 수 있습니다.

walk(
    if type == "object" then 
     with_entries(select(.value != null)) 
    elif type == "array" then 
     map(select(. != null)) 
    else 
     . 
    end 
) 

당신은 입력이 있었다 그래서 경우 :

{ 
    "foo": null, 
    "bar": "bar", 
    "biz": [1,2,3,4,null], 
    "baz": { 
     "a": 1, 
     "b": null, 
     "c": ["a","b","c","null",32,null] 
    } 
} 

이 필터는 얻을 것이다 : 당신이해야합니다, 그래서

{ 
    "bar": "bar", 
    "baz": { 
     "a": 1, 
     "c": ["a","b","c","null",32] 
    }, 
    "biz": [1,2,3,4] 
} 

walk/1은 JQ의 향후 버전에 추가 될 예정입니다 그것을 추가하십시오. here 정의를 가져올 수 있습니다.

# Apply f to composite entities recursively, and to atoms 
def walk(f): 
    . as $in 
    | if type == "object" then 
     reduce keys[] as $key 
     ({}; . + { ($key): ($in[$key] | walk(f)) }) | f 
    elif type == "array" then map(walk(f)) | f 
    else f 
    end; 
+0

Jeff의 문자열 배열을 내 보낸 내장 함수가 있습니다. walk 함수를 사용하면 다음과 같이 쓸 수 있습니다. walk (type == "object"then with_entries (elif type == "array"그런 다음 map (select (.! = null)) else. end). 둘째, 개발 버전에서 walk/1을 이미 사용할 수 있습니다. – peak

+0

아, 네 말이 맞아, 나는 그것이 깊이 먼저 간다는 것을 몰랐다. 감사. –

3

@ jeff-mercado로 스크립트의 확장 버전을 강조하기 위해 새로운 대답을 추가하고 있습니다. 스크립트의 제 버전에서는 다음과 같이 빈 값이 있다고 가정합니다.

  • null;
  • [] - 빈 배열;
  • {} - 빈 개체.

여기에서 https://stackoverflow.com/a/26196653/3627676에서 빈 배열 및 개체를 제거했습니다.

def walk(f): 
    . as $in | 
    if type == "object" then 
     reduce keys[] as $key 
      ({}; . + { ($key): ($in[$key] | walk(f)) }) | f 
    elif type == "array" then 
     select(length > 0) | map(walk(f)) | f 
    else 
     f 
    end; 

walk(
    if type == "object" then 
     with_entries(select(.value != null and .value != {} and .value != [])) 
    elif type == "array" then 
     map(select(. != null and . != {} and .!= [])) 
    else 
     . 
    end 
) 
+0

'def walk (f)'에'select (length> 0) |'를 추가하는 것은 실수입니다. 일부 JSON의 경우 비어 있지 않은 배열을 제거합니다. 다른 JSON (예 : 일부 null 및 빈 구조가 포함 된 중첩 된 객체)의 경우 '{}'만 반환되었습니다. 그러나 여기에 표시된 조건은 원래 'walk'정의와 함께 작동합니다. 방금이 문제를 알았으므로 어제 나 한 표를 변경할 수 없습니다. –

1

earlier answer 정교화, null 값 속성을 제거하는 이외에, 너무 빈 어레이 또는 목적 값 (즉, [] 또는 {})와 JSON 속성을 제거하는 것이 도움이된다.

는 ℹ️ - JQ의 walk() 기능 (walk/1)이 쉽게한다. walk()은이고 jq (>jq-1.5)의 차후 버전에서 사용할 수 있지만 its definition 은 현재 필터에 추가 할 수 있습니다.

조건 널 빈 구조물을 제거 walk() 전달할 것은이 JSON 입력 주어

walk(
    if type == "object" then with_entries(select(.value|length > 0)) 
    elif type == "array" then map(select(length > 0)) 
    else . 
    end 
) 

:

{ 
    "notNullA": "notNullA", 
    "objectA": { 
    "notNullB": "notNullB", 
    "objectB": { 
     "notNullC": "notNullC" 
    }, 
    "arrayB": [ 
     "b" 
    ] 
    }, 
    "arrayA": [ 
    "a" 
    ] 
} 
:

{ 
    "notNullA": "notNullA", 
    "nullA": null, 
    "objectA": { 
    "notNullB": "notNullB", 
    "nullB": null, 
    "objectB": { 
     "notNullC": "notNullC", 
     "nullC": null 
    }, 
    "emptyObjectB": {}, 
    "arrayB": [ 
     "b" 
    ], 
    "emptyBrrayB": [] 
    }, 
    "emptyObjectA": {}, 
    "arrayA": [ 
    "a" 
    ], 
    "emptyArrayA": [] 
} 

이 기능을 사용하여 결과를 준다