使用jq分配多个输出变量

时间:2017-04-08 07:26:41

标签: bash jq television

我正在尝试使用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'只是为了尝试让一个人工作。我不了解文档,或者即使它是我正在寻找的内容。有没有办法做我想做的事情?

3 个答案:

答案 0 :(得分:5)

jq始终生成零个或多个值的流。例如,要生成对应于“episodeName”和“id”的两个值,您可以写:

.data[] | ( .episodeName, .id )

出于您的目的,使用-c命令行选项可能会有所帮助,以确保每行JSON输出值都显示在一行上。您可能还希望使用-r命令行选项,该选项从每个输出值(JSON字符串)中删除最外面的引号。

有关更多信息,请参阅常见问题解答https://github.com/stedolan/jq/wiki/FAQ,例如问题:

  

问:如何将jq生成的JSON文本流转换为相应值的bash数组?

答案 1 :(得分:1)

您可以对read使用单独的变量:

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

absoluteNumberairedEpisodeNumberepisodeName&amp; overview分别是${data[0]}${data[1]}${data[2]}${data[3]}set -fset +f分别用于禁用&amp;启用globbing

对于jq部分,所有必填字段都会使用'|' <{1}}字符进行映射和分隔。

如果你正在使用jq&lt; 1.5,您必须为每个Number字段将Number转换为String join("|"),例如:

tostring

答案 2 :(得分:-2)

将引用的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/"\([^"]*\)":/[\1]=/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.'