将 jq 输出设置为 Bash 变量

将 jq 输出设置为 Bash 变量

我正在使用curl从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

您可以将 bash 内置函数read与将 jq 的输出连接到 FIFO 的进程替换一起使用:

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

只要您只需要分配一个 jq 值,其他建议的解决方案就更简单。read当您需要一次将多个键分配给多个 shell 变量时,当前的解决方案非常有用;然后你只需要使用read var1 var2 var3 < <(...).

这里有一些更通用的代码片段,用于将 jq 输出分配给 shell 变量,这非常方便。

单行输入(不循环)的两种方法:

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'readarray代替read(参见下面的示例)。

多行输入的三种方法(带循环):

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"

相关内容