jq 출력을 Bash 변수로 설정

jq 출력을 Bash 변수로 설정

다음과 같이 REST API에서 JSON을 반환하기 위해 컬을 사용하고 있습니다.

content=$(curl -s  -X GET -H "Header:Value" http://127.0.0.1:8200/etc)
echo "${content}"| jq -r '.data.value'

그것은 나에게 필요한 가치를 생산합니다. 그러나 위의 코드를 다음과 같이 변경하면:

content=$(curl -s  -X GET -H "Header:Value" http://127.0.0.1:8200/etc)
username=$(echo "${content}"| jq -r '.data.value')
echo $username

아무것도 생산되지 않습니다. 출력이 사용자 이름 변수에 할당되도록 이를 어떻게 변경할 수 있습니까?

답변1

코드를 다음으로 변경했는데 작동했습니다.

content=$(curl -s  -X GET -H "Header:Value" http://127.0.0.1:8200/etc) 
username=$( jq -r  '.data.value' <<< "${content}" ) 
echo "${username}"

답변2

다음과 같이 한 줄로 변환할 수 있습니다.

username=$( curl -s  -X GET -H "Header:Value" http://127.0.0.1:8200/etc |  jq -r  '.data.value' ) 
echo ${username}

답변3

이는 두 번째 줄의 "에코"가 손실된 경우에만 작동합니다.

content=$(curl -s  -X GET -H "Header:Value" http://127.0.0.1:8200/etc) 
username=$( echo jq -r  '.data.value' <<< "${content}" ) 
echo ${username}

답변4

readjq의 출력을 FIFO에 연결하는 프로세스 대체와 함께 내장된 bash를 사용할 수 있습니다 .

read username < <(curl -s -X GET -H "Header:Value" http://127.0.0.1:8200/etc | jq -r '.data.value')

다른 제안된 솔루션은 jq 값만 할당하면 되는 한 더 간단합니다. read현재 솔루션은 여러 키를 여러 쉘 변수에 한 번에 할당해야 할 때 유용합니다 read var1 var2 var3 < <(...).

다음은 jq 출력을 쉘 변수에 할당하는 좀 더 일반적인 코드 조각입니다. 이는 매우 편리합니다.

단일 라인 입력을 위한 두 가지 방법(루핑 없음):

IFS=$'\n' read -rd '' a b < <(echo '{"a":"1","b":"2"}' | jq -r '(.a, .b)'); declare -p a b
  declare -- a="1"
  declare -- b="2"

read a b < <(echo '{"a":"1","b":"2"}' | jq -r '[.[]] | @tsv'); declare -p a b
  declare -- a="1"
  declare -- b="2"

참고 1: @tsv는 공백 구분 기호를 사용합니다. 공백을 포함할 수 있는 값에는 @csv 형식을 사용할 수 있습니다. 참고 2: IFS=$'\n' read -rd '' a b <비어 있는 출력 행이 없다고 가정합니다. 일부 json 키가 비어 있으면 '--raw' 없이 'jq'를 사용한 다음 "'s'를 제거 하거나 대신 a=${a:1:-1}'s'를 사용할 수 있습니다 (아래 예 참조).readarrayread

여러 줄 입력을 위한 세 가지 방법(루프 포함):

echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
  jq -r '.[] | {a, b} | [.[]] | @csv' |
  while IFS= read -r i; do
    IFS=, read -r a b <<< "$i"; a=${a:1:-1}; b=${b:1:-1}; declare -p a b;
  done

  declare -- a="1"
  declare -- b="2"
  declare -- a="3"
  declare -- b="4"

echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
  jq -r '.[] | (.a, .b)' |
  while IFS= read -r a; do
    IFS= read -r b; declare -p a b;
  done

  declare -- a="1"
  declare -- b="2"
  declare -- a="3"
  declare -- b="4"

echo '[{"a":"1","b":"2"},{"a":"3","b":"4"}]' |
  jq -r '.[] | (.a, .b)' |
  while readarray -n2 lines && [ ${#lines} -ne 0 ]; do
    a="${lines[0]:0:-1}"; b="${lines[1]:0:-1}"; declare -p a b;
  done

  declare -- a="1"
  declare -- b="2"
  declare -- a="3"
  declare -- b="4"

관련 정보