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