繁体   English   中英

Bash脚本使用jq遍历多行JSON对象

[英]Bash script traversing a multi-line JSON object using jq

我必须卷曲到一个站点(statuscake.com),该站点以JSON返回多个项目,其中每行包含多个项目。 我想从每行中提取其中两个,WebsiteName和TestID,因此我可以检查WebsiteName是否与我感兴趣的匹配,将TestID取出并将其传递给第二个curl语句以删除测试。

尽管更为复杂,但返回的JSON本质上具有以下形式

[{"TestID": 123, "WebsiteName": "SomeSite1"}, {"TestID": 1234, "WebsiteName": "SomeSite2"}]

我似乎找不到一个神奇的jq命令来一次完成所有操作-如果有一个,我会很高兴看到它。

我有

cat $data | jq '[.[] | .WebsiteName]' 

以获得一组网站名称(与TestIDs非常相似),但我认为我做得有些愚蠢。数据是从curl返回的信息,用于获取JSON,因此填充好。

我希望能够将它们分配给两个数组,即名称和ID,然后在名称中搜索相关名称的索引,从ID中获取ID并将其传递给curl。 除非有更好的方法。

有什么建议吗?

通过使用类似XPath的查询选择JSON,我的Xidel可以一次完成所有操作:

例如,从对象数组中返回WebsiteName包含“ site2”的所有ID:

xidel /tmp/x.json -e '$json()[contains((.).WebsiteName, "site2")]/TestID'

或者,例如,下载原始JSON,然后使用ID发出HTTP请求:

xidel http://statuscake.com/your-url... -f '$json()[contains((.).WebsiteName, "site2")]/TestID!x"/your-delete-url{.}..."'

如果我的问题正确.WebsiteName == "needle" ,这听起来像是您想要的,对于每个元素,选择.WebsiteName == "needle"那些元素,然后从中获取.TestID 您可以这样做:

.[] | select(.WebsiteName == "needle") | .TestID

如果要使用数组作为结果,可以将以上脚本包装在方括号中。

该JQ过滤器startswithendswith可能是你的兴趣。 如果要将结果传递回cURL,您可能还对@sh格式过滤器和-r命令行标志感兴趣。

假设您的bash为4+,并假设json有效(字符串中不包含换行符,等等),则此方法有效:

$ echo "$data"
[{"TestID": 123, "WebsiteName": "SomeSite1"}, {"TestID": 1234, "WebsiteName":
"SomeSite2"}, {"TestID": 555, "WebsiteName": "foo*ba@r blah[54]quux{4,5,6}"}]
$ declare -A arr
$ while IFS= read -r line; do
    eval "$line"
done < <(jq -M -r '.[] | @sh "arr[\(.WebsiteName)]+=\(.TestID)"' <<<"$data")
$ declare -p arr
declare -A arr='(["foo*ba@r blah[54]quux{4,5,6}"]="555" [SomeSite2]="1234" [SomeSite1]="123" )'

这是仅使用jq原语的解决方案。

  .[]
| if .WebsiteName == "SomeSite1" then .TestID else empty end

这基本上与Santiago的答案相同,但是如果您不熟悉jq,它可能会提供参考,因为select / 1定义为

 def select(f): if f then . else empty end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM