bash 변수를 jq에 전달


112

에서 특정 값을 검색하는 스크립트를 작성했습니다 file.json. jq에 값을 제공하면 작동 select하지만 변수가 작동하지 않는 것 같습니다 (또는 사용 방법을 모릅니다).

#!/bin/sh

#this works ***
projectID=$(cat file.json | jq -r '.resource[] | select(.username=="myemail@hotmail.com") | .id')
echo "$projectID"

EMAILID=myemail@hotmail.com

#this does not work *** no value is printed
projectID=$(cat file.json | jq -r '.resource[] | select(.username=="$EMAILID") | .id')
echo "$projectID"

관련 문제 : bash 변수를 jq 필터에 전달하면 구문이 약간 다릅니다. jq -r --arg var "$var" '.[$var]' stackoverflow.com/questions/34745451/…
enharmonic

답변:


176

또한 쉘 변수 (EMAILID)를 jq 변수로 전달하는 것을 고려하십시오 (여기에서는 설명을 위해 EMAILID도 있음).

   projectID=$(cat file.json | 
     jq -r --arg EMAILID "$EMAILID" '
        .resource[]
        | select(.username==$EMAILID) 
        | .id')

추신

기록을 위해 또 다른 가능성은 env환경 변수에 액세스 하기 위해 jq의 함수 를 사용하는 것 입니다. 예를 들어 다음 bash 명령 시퀀스를 고려하십시오.

EMAILID=foo@bar.com  # not exported
EMAILID="$EMAILID" jq -n 'env.EMAILID'

출력은 JSON 문자열입니다.

"foo@bar.com"

4
이것이 유일한 100 % 안전한 대답입니다. jq필터 로 해석 bash되는 문자열을 만드는 데 사용 하는 대신 값을 사용하여 필터를 올바르게 만들 수 있습니다 jq. (값에 EMAILID가 포함 된 경우 어떤 일이 발생하는지 고려하십시오 ).)
chepner

3
감사합니다. 제공된 솔루션은 내가 찾던 적절한 응답입니다. 예, 작동합니다.
asidd

내 사용 사례는 작동합니다! function n2 { termux-contact-list |jq -r --arg v1 "$1" '.[] | select(.name==$v1)|.number' }전화 :n2 Name1
Timo

2
참고로, jq의 env함수는 jq 1.4와 1.5+ 사이에서 변경되므로 env.EMAILID(이 답변의 예에서)에 대한 참조 는 jq 1.4에서 작동하지 않으므로 jq 1.4 --arg EMAILID "$EMAILID"를 사용해야하는 경우 구성을 사용하는 것이 좋습니다 . 도움이 되었기를 바랍니다; 단지 자신이이를 알아 내기 위해 나에게 하루에 +를했다)
m0j0hn

3
를 사용하여 전달 된 인수는 --arg문자열로 전달됩니다. 다른 JSON 유형의 데이터를 전달하려면을 사용하십시오 --argjson. 그러면 문자열이 JSON으로 구문 분석됩니다. 예 :--argjson myObj '{"a": [1, 2]}'
BallpointBen

25

내부 큰 따옴표를 이스케이프하여이 문제를 해결했습니다.

projectID=$(cat file.json | jq -r ".resource[] | select(.username==\"$EMAILID\") | .id")

--arg가 잘 작동하지 않기 때문에 이것을 사용하고 있습니다.-c
Dimitris Moraitidis

9

견적 문제입니다. 다음이 필요합니다.

projectID=$(
  cat file.json | jq -r ".resource[] | select(.username=='$EMAILID') | .id"
)

당신이 넣을 경우 작은 따옴표를 주요 문자열을 구분하기 위해, 쉘은 소요 $EMAILID그대로.

"큰 따옴표"공간 / 메타 문자 및 포함하는 모든 문자 그대로 모든 확장 : "$var", "$(command "$var")", "${array[@]}", "a & b". 사용 'single quotes'코드 나 문자에 대한 $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. 참조
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words을


내 경우에도 따옴표를 사용하지 않으면 비슷합니다 termux-contact-list |jq -r '.[] | select(.name=='$1')|.number'. 결과 :jq Compile error
Timo

6
이 댓글이 왜 그렇게 여러 번 투표되었는지 잘 모르겠습니다. 예, 큰 따옴표는 변수 확장을 허용하지만 jq작은 따옴표는 좋아하지 않습니다.jq: error: syntax error, unexpected INVALID_CHARACTER (Unix shell quoting issues?)
jdelman

입력이 일반 json이면 해당 값은 작은 따옴표가 아닌 큰 따옴표로 표시됩니다. 작동하는 것 : jq의 전체 인수에 대해 큰 따옴표를 사용하고 @asid가 대답 한 것처럼 내부의 큰 따옴표 (`\`로)를 이스케이프합니다.
GuSuku

6

다른 사람들에게 도움이 될 수 있으므로 여기에 게시하십시오. 문자열에서 따옴표를 jq에 전달해야 할 수도 있습니다. jq로 다음을 수행하려면 :

.items[] | select(.name=="string")

bash에서 당신은 할 수 있습니다

EMAILID=$1
projectID=$(cat file.json | jq -r '.resource[] | select(.username=='\"$EMAILID\"') | .id')

본질적으로 따옴표를 이스케이프하고 jq에 전달


완벽하게 작동합니다. 빠른 솔루션을 찾는 사람에게는 너무 복잡하지 않습니다.
Mo-Gang

4

이를 수행하는 또 다른 방법은 jq "--arg"플래그를 사용하는 것입니다. 원래 예 사용 :

#!/bin/sh

#this works ***
projectID=$(cat file.json | jq -r '.resource[] | 
select(.username=="myemail@hotmail.com") | .id')
echo "$projectID"

EMAILID=myemail@hotmail.com

# Use --arg to pass the variable to jq. This should work:
projectID=$(cat file.json | jq --arg EMAILID $EMAILID -r '.resource[] 
| select(.username=="$EMAILID") | .id')
echo "$projectID"

이 솔루션을 찾은 곳은 https://github.com/stedolan/jq/issues/626입니다.


2

회신 할 시간이 조금 늦다는 것을 알고 있습니다. 죄송합니다. 그러나 그것은 나를 위해 작동합니다.

export K8S_public_load_balancer_url="$(kubectl get services -n ${TENANT}-production -o wide | grep "ingress-nginx-internal$" | awk '{print $4}')"

이제 변수의 내용을 가져 와서 jq에 전달할 수 있습니다.

export TF_VAR_public_load_balancer_url="$(aws elbv2 describe-load-balancers --region eu-west-1 | jq -r '.LoadBalancers[] | select (.DNSName == "'$K8S_public_load_balancer_url'") | .LoadBalancerArn')"

제 경우에는 변수 값에 액세스하기 위해 큰 따옴표와 따옴표를 사용해야했습니다.

건배.


1

Jq는 이제 환경 변수에 액세스하는 더 좋은 방법을 가지고 있으며 env.EMAILI를 사용할 수 있습니다.

projectID=$(cat file.json | jq -r ".resource[] | select(.username==env.EMAILID) | .id")

0

약간 관련이 없지만 여기에 넣겠습니다. 다른 실용적인 목적으로 쉘 변수를 다음과 같이 사용할 수 있습니다.

value=10
jq  '."key" = "'"$value"'"' file.json
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.