![](/img/trans.png)
[英]When bash jq parsing json ,return a multi-line array but, how can I use this result?
[英]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过滤器startswith
和endswith
可能是你的兴趣。 如果要将结果传递回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.