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

时间:2015-04-14 13:03:11

标签: json bash curl jq

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

虽然它更复杂,但返回的JSON基本上是

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

我似乎无法找到一个神奇的jq命令来完成所有这一切 - 如果有的话,我很高兴看到它。

我有

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

获取一系列网站名称(以及一个非常类似的TestIDs,但我认为我已经做了一些愚蠢的事情。数据是从卷曲中回来的信息,以获得JSON和那个&#39 ; s填充好。

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

请问任何建议?

4 个答案:

答案 0 :(得分:2)

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

E.g。从对象数组中返回WebsiteName包含“site2”的所有ID:

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

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

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

答案 1 :(得分:2)

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

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

如果您想要一个数组作为结果,您可以将上面的脚本包装在方括号中。

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

答案 2 :(得分:1)

假设你有一个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" )'

答案 3 :(得分:1)

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

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

这与Santiago的答案基本相同,但如果您是jq的新手,可能会提供信息,因为select/1被定义为

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