2016-11-09 3 views
2

주어진 선택기가 jq 인 경우 입력기가 주어지면 선택기가 성공했는지 실패했는지 알고 싶습니다.null 또는 false가 유효한 결과일지도 모르는 경우에 jq 선택기가 성공했는지 실패했는지 어떻게 판단 할 수 있습니까?

% jq -re .bad <<<'{}' 
null 
% echo $? 
1 
% 

그러나 잘못 다음은 (지금까지 내 요구가 가서) 오류 상태를 나타냅니다 : 위의 문제가 있다는 것입니다

% jq -re .key <<<'{"key":false}' 
false 
% echo $? 
1 
% 

예를 들어, 올바르게 다음은 오류 상태를 나타냅니다 마지막 출력 값이 false 또는 null이면 -e 옵션은 1의 리턴 상태를 제공합니다. 그러나 false 및 null 값이 JSON 입력에있는 경우이 반환 상태는 오류가 발생했다는 잘못된 인상을줍니다.

나는 강제로 반환 코드 1의 경우 키가 있는지 확인합니다. 예를 들어

#!/bin/bash 

Result=$(jq -re .key <<<'{"key":false}') 
Status=$? 
if [[ $Status -eq 1 ]] ; then 
    jq -re '. | has("key")' <<<'{"key":false}' && (exit 0) || (exit 1) 
else 
    (exit $Status) 
fi 

# At this point $? can be relied on to indicate success/failure 

은 상기 용액을 0 (1)의 반송 상태를 변경하고 간단한 JQ 선택기 허용하지만,이 솔루션은 거짓 또는 null 유효한 결과를 생성 할 수 계산 선택기의 만족스럽지 않은 것이다.

그래서하는 JQ 선택이 정말 성공 또는 falsenull 같은 결과가 될 수도 있고 유효 또는 무효가 선택 및 입력

을 따라 점을 감안, (심지어 계산 선택기) 실패 여부를 알 수있는 방법이있다

솔루션은 Bash 4.2 이상에서 수행해야합니다.

답변

0

필터의 최종 결과에만 의존한다는 것을 기억하십시오. 따라서 마지막에 필터의 일부로 수표를 추가하는 것이 더 쉽습니다. 마지막 결과를 무시하는 것만 기억하면됩니다.

$ jq -re --arg key 'key' '.[$key], has($key)' <<< '{"key":false}' 
false 
true 
$ echo $? 
0 
+0

불행히도, 선택자는 내가 질문에 넣은 경우가 아닙니다. 그리고, 나는 이미 추가 파싱이 필요없는이 경우에 대한 해결책을 게시했다. 계산 선택기 (비 키 선택기)에서는 프로세스가 단순하지 않습니다. 궁극적으로는 오류 상태를 나타내는 jq 옵션입니다. 이제는 해결 방법/솔루션을 별도로 간단한 선택기 경우 다른 계산 선택기를 처리하는 조합이 될 필요가 있다고 생각 해요. –

0

당신이 하려고하는,하지만 난 당신이 그것에 대해 잘못된 길을 가고있는 느낌이 무엇인지 나에게 완전히 명확하지 않다. 문제의 일부는 전문 용어 문제로 인한 것일 수 있습니다. 이를 피하기 위해 JSON 및 jq에 적합한 용어를 채택 할 것입니다.

먼저 jq에서 {} | .a과 같은 표현은 오류로 간주되지 않습니다. 당신이 존재하지 않는 키의 값에 액세스를 시도하면 오류 조건이 당신과 같이 쓸 수 , 제기하려면 다음의 경우를 구분하는

if has("a") then .a else error("no such key") end 

또 다른 방법을 때 입력 오브젝트

이있는 경우 ("A")를 더 컴팩트하게 .A 다른 빈 말

나 :

선택 키와 경우는 키 같은 것을 작성하는 것입니다없는있다 (h as ("a")) | .다음 배쉬 할당에 의해 도시 된 바와 같이

당신은 JQ의 -c 옵션과 함께이 기술을 사용할 수 있습니다

result=$(jq -c 'select(has("a")) | .a' INPUT.json) 
n=$(wc -l <<< "$result") 

그런 다음 $ n의 값을 확인할 수 있습니다.

+0

일반적으로 필터는 단순한 키가 아니라 계산 일 수 있습니다. .value '<<<'[{ "user": "steve", "value"} [예]''jq -r -arg Name $ (whoami) '. [] | select (.user == $ Name) : false}, { "user": "tom", "value": true}] ''. 로그인 한 사용자가'steve'이면 성공한 결과는'false'이고 리턴 코드는 0이어야합니다. 로그인 한 사용자가'mary'이면 리턴 코드는 0이 아니어야합니다. 위의 코드는 모든 경우에 반환 코드가 0입니다. 이것이 문제입니다. –

0

나는이 필터가 작동합니다 생각 :

map(select(.user==$Name and .value==true))[0] or error($Name) 

예 :

#!/bin/bash 
for i in steve tom mary; do 
    echo '[{"user":"steve", "value":false},{"user":"tom", "value":true}]' \ 
    | jq -M -r --arg Name $i 'map(select(.user==$Name and .value==true))[0] or error($Name)' 
    echo $i $? 
done 

출력 : stevemary JQ의 경우 그래서

jq: error (at <stdin>:1): steve 
steve 5 
true 
tom 0 
jq: error (at <stdin>:1): mary 
mary 5 

이 0이 아닌 종료를 반환 상태가되고 tom의 경우 0 인 exit statu를 반환합니다. 에스.