2016-10-19 3 views
1

JSON에서 인용 된 JSON을 구문 분석해야하는 경우가 있습니다. 어떤 (선택 사항) 속성에는 인용 된 JSON이 포함되며 그렇지 않은 속성이 있습니다. 따라서 속성 키가 가능한 키 목록에 있는지 확인하고 싶습니다. 이미 다음을 가지고 있습니다 :jq : 키가 미리 정의 된 키 목록에 있는지 테스트합니다.

# attributes "a" and "b" contain quoted JSON 
echo '{"a":"{\"x\":1}","y":2}' | 
jq -c ' 
    def is_json($o): ["a","b"] | (map(select(. == $o)) | length) > 0; 
    with_entries(if is_json(.key) then .value = (.value|fromjson) else . end) 
' 

이것은 이미 원하는 출력을 생성합니다 : {"a":{"x":1},"y":2}. 그러나, 속성 이름의 검사는 jq 내장 기능을 많이 제공 주어, 서투른 보이는 등 has, in, contains, inside, 같은

질문 :이 경우 확인하는 더 나은 방법이 있나요 속성 키가 주어진 목록에 있습니까?

편집 : 여기 피크의 답변을 기준으로 한 현재 해결책이 있습니다.

#!/bin/bash 
to_array_string() { echo "$*" | awk -v OFS='","' 'NF > 0 {$1=$1; print "\""$0"\""}'; } 
to_json_array_string() { echo "["`to_array_string "[email protected]"`"]"; } 

parse_json_jq() { jq -c " 
    reduce keys[] as \$key 
    (.; if any((`to_array_string "[email protected]"`); . == \$key) and .[\$key] != null then .[\$key] |= fromjson else . end) 
";} 

답변

2
프로그램을 향상시킬 수있는 세 가지 방법

:

  1. (효율) (is_json에서) 불필요한 어레이의 생성을 방지;
  2. 불필요하게 반복하지 않도록 "단락"의미 체계를 사용하여 (효율);
  3. (효율성) with_entries와 관련된 생성/해체를 피하십시오.

대체로 여기에 제시된 대안이 더 간단하고 간결하며 가독성이 있다는 데 동의 할 것입니다.

나중에 JQ 또는 버전 1.5이있는 경우, 모든/2를 사용했다 할 수있다 주요 개선 사항 : 또한

def is_json($o): any(("a","b"); . == $o); 

with_entries(if is_json(.key) then .value |= fromjson else . end) 

공지 사항의 사용 '| ='당신 '='사용했다. 당신의 JQ가 any/2가없는 경우는 단락의 의미가 부족하지만

가, 다음, 다음 정의를 사용할 수 있습니다 마지막으로

def any(s): reduce s as $i (false; . == true or $i); 

with_entries을 사용하지, 당신은 reduce을 사용하고 is_json을 제거 할 수 전체 :

reduce keys[] as $key 
    (.; if any(("a","b"); . == $key) then .[$key] |= fromjson else . end) 
+0

이 솔루션의 경우 Thx입니다. 난 그냥 다른 'null' 확인을 추가하여 작동하게 만들 필요가 있습니다 (질문 편집 참조). – Juve