使用 jq 分配多个输出变量
using jq to assign multiple output variables
我正在尝试使用 jq
来解析来自 TVDB api 的信息。我需要提取几个字段并将值分配给我可以在 bash
脚本中继续使用的变量。我知道我可以通过 bash 和 variable="$(command)"
轻松地将输出分配给一个变量,但我需要输出来产生多个变量,我不想使用多个命令。
我阅读了这份文档:
https://stedolan.github.io/jq/manual/v1.5/#Advancedfeatures
但我不知道这是否与我正在尝试做的相关。
jq '.data'
产生以下输出:
[
{
"absoluteNumber": 51,
"airedEpisodeNumber": 6,
"airedSeason": 4,
"airedSeasonID": 680431,
"dvdEpisodeNumber": 6,
"dvdSeason": 4,
"episodeName": "We Will Rise",
"firstAired": "2017-03-15",
"id": 5939660,
"language": {
"episodeName": "en",
"overview": "en"
},
"lastUpdated": 1490769062,
"overview": "Clarke and Roan must work together in hostile territory in order to deliver an invaluable asset to Abby and her team."
}
]
我尝试了 jq '.data | {episodeName:$name}'
和 jq '.data | .episodeName as $name'
只是为了尝试让一个工作。我不理解文档,即使它是我正在寻找的。有没有办法做我想做的事?
您可以将单独的变量与 read
一起使用:
read var1 var2 var3 < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |
jq -r '.id, .name, .full_name'))
echo "id : $var1"
echo "name : $var2"
echo "full_name : $var3"
使用数组:
read -a arr < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |
jq -r '.id, .name, .full_name'))
echo "id : ${arr[0]}"
echo "name : ${arr[1]}"
echo "full_name : ${arr[2]}"
你也可以用一些字符拆分 jq 输出:
IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |
map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |
join("|")) | join("\n")')
或者使用像这样的数组:
set -f; IFS='|' data=($(curl '......' | jq -r '.data |
map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |
join("|")) | join("\n")')); set +f
absoluteNumber
、airedEpisodeNumber
、episodeName
、overview
分别为${data[0]}
、${data[1]}
、${data[2]}
、${data[3]}
。 set -f
和set +f
分别用于禁用和启用globbing。
对于 jq 部分,所有必填字段都已映射并使用 '|'
字符和 join("|")
分隔
如果您使用的是 jq < 1.5,则必须为每个数字字段使用 tostring
将数字转换为字符串,例如:
IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |
map([.absoluteNumber|tostring, .airedEpisodeNumber|tostring, .episodeName, .overview] |
join("|")) | join("\n")')
jq 总是产生零个或多个值的流。例如,要生成对应于 "episodeName" 和 "id"' 的两个值,您可以这样写:
.data[] | ( .episodeName, .id )
为了您的目的,使用 -c 命令行选项可能会有所帮助,以确保每个 JSON 输出值显示在一行中。您可能还想使用 -r 命令行选项,它会从 JSON 字符串的每个输出值中删除最外层的引号。
有关更多变化,请参阅 jq 常见问题解答 https://github.com/stedolan/jq/wiki/FAQ,例如问题:
Q: How can a stream of JSON texts produced by jq be converted into a bash array of corresponding values?
引用的 OP 输入(tv.dat)到一系列 bash
变量(和数组)的实验性转换。 jq
代码主要是从各处借来的,但我不知道如何让 jq
在数组中展开一个数组,所以 sed
代码就是这样做的,(那是仅适用于一个级别,但 bash
数组也是如此):
jq -r ".[] | to_entries | map(\"DAT_\(.key) \(.value|tostring)\") | .[]" tv.dat |
while read a b ; do echo "${a,,}='$b'" ; done |
sed -e '/{.*}/s/"\([^"]*\)":/[]=/g;y/{},/() /' -e "s/='(/=(/;s/)'$/)/"
输出:
dat_absolutenumber='51'
dat_airedepisodenumber='6'
dat_airedseason='4'
dat_airedseasonid='680431'
dat_dvdepisodenumber='6'
dat_dvdseason='4'
dat_episodename='We Will Rise'
dat_firstaired='2017-03-15'
dat_id='5939660'
dat_language=([episodeName]="en" [overview]="en")
dat_lastupdated='1490769062'
dat_overview='Clarke and Roan must work together in hostile territory in order to deliver an invaluable asset to Abby and her team.'
我正在尝试使用 jq
来解析来自 TVDB api 的信息。我需要提取几个字段并将值分配给我可以在 bash
脚本中继续使用的变量。我知道我可以通过 bash 和 variable="$(command)"
轻松地将输出分配给一个变量,但我需要输出来产生多个变量,我不想使用多个命令。
我阅读了这份文档:
https://stedolan.github.io/jq/manual/v1.5/#Advancedfeatures
但我不知道这是否与我正在尝试做的相关。
jq '.data'
产生以下输出:
[
{
"absoluteNumber": 51,
"airedEpisodeNumber": 6,
"airedSeason": 4,
"airedSeasonID": 680431,
"dvdEpisodeNumber": 6,
"dvdSeason": 4,
"episodeName": "We Will Rise",
"firstAired": "2017-03-15",
"id": 5939660,
"language": {
"episodeName": "en",
"overview": "en"
},
"lastUpdated": 1490769062,
"overview": "Clarke and Roan must work together in hostile territory in order to deliver an invaluable asset to Abby and her team."
}
]
我尝试了 jq '.data | {episodeName:$name}'
和 jq '.data | .episodeName as $name'
只是为了尝试让一个工作。我不理解文档,即使它是我正在寻找的。有没有办法做我想做的事?
您可以将单独的变量与 read
一起使用:
read var1 var2 var3 < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |
jq -r '.id, .name, .full_name'))
echo "id : $var1"
echo "name : $var2"
echo "full_name : $var3"
使用数组:
read -a arr < <(echo $(curl -s 'https://api.github.com/repos/torvalds/linux' |
jq -r '.id, .name, .full_name'))
echo "id : ${arr[0]}"
echo "name : ${arr[1]}"
echo "full_name : ${arr[2]}"
你也可以用一些字符拆分 jq 输出:
IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |
map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |
join("|")) | join("\n")')
或者使用像这样的数组:
set -f; IFS='|' data=($(curl '......' | jq -r '.data |
map([.absoluteNumber, .airedEpisodeNumber, .episodeName, .overview] |
join("|")) | join("\n")')); set +f
absoluteNumber
、airedEpisodeNumber
、episodeName
、overview
分别为${data[0]}
、${data[1]}
、${data[2]}
、${data[3]}
。 set -f
和set +f
分别用于禁用和启用globbing。
对于 jq 部分,所有必填字段都已映射并使用 '|'
字符和 join("|")
如果您使用的是 jq < 1.5,则必须为每个数字字段使用 tostring
将数字转换为字符串,例如:
IFS='|' read var1 var2 var3 var4 < <(curl '......' | jq -r '.data |
map([.absoluteNumber|tostring, .airedEpisodeNumber|tostring, .episodeName, .overview] |
join("|")) | join("\n")')
jq 总是产生零个或多个值的流。例如,要生成对应于 "episodeName" 和 "id"' 的两个值,您可以这样写:
.data[] | ( .episodeName, .id )
为了您的目的,使用 -c 命令行选项可能会有所帮助,以确保每个 JSON 输出值显示在一行中。您可能还想使用 -r 命令行选项,它会从 JSON 字符串的每个输出值中删除最外层的引号。
有关更多变化,请参阅 jq 常见问题解答 https://github.com/stedolan/jq/wiki/FAQ,例如问题:
Q: How can a stream of JSON texts produced by jq be converted into a bash array of corresponding values?
引用的 OP 输入(tv.dat)到一系列 bash
变量(和数组)的实验性转换。 jq
代码主要是从各处借来的,但我不知道如何让 jq
在数组中展开一个数组,所以 sed
代码就是这样做的,(那是仅适用于一个级别,但 bash
数组也是如此):
jq -r ".[] | to_entries | map(\"DAT_\(.key) \(.value|tostring)\") | .[]" tv.dat |
while read a b ; do echo "${a,,}='$b'" ; done |
sed -e '/{.*}/s/"\([^"]*\)":/[]=/g;y/{},/() /' -e "s/='(/=(/;s/)'$/)/"
输出:
dat_absolutenumber='51'
dat_airedepisodenumber='6'
dat_airedseason='4'
dat_airedseasonid='680431'
dat_dvdepisodenumber='6'
dat_dvdseason='4'
dat_episodename='We Will Rise'
dat_firstaired='2017-03-15'
dat_id='5939660'
dat_language=([episodeName]="en" [overview]="en")
dat_lastupdated='1490769062'
dat_overview='Clarke and Roan must work together in hostile territory in order to deliver an invaluable asset to Abby and her team.'