使用bash返回json对象中的特定项

时间:2018-06-01 19:28:07

标签: arrays json bash curl jq

我试图用多个对象接受json响应(来自我的linux comp上安装的curl命令和jq),并使用for循环编辑每个对象。问题是我不明白如何将每个{}转换为单独的对象。例如,我的json响应是:

{
  "Name": "testuser1",
  "Username": "testuser1",
  "Url": "www.test1.com"
}
{
  "Name": "testuser2",
  "Username": "testuser2",
  "Url": "www.test2.com"
}

理想情况下,我想用数字来表示每一个。例如" echo $ item | jq' .Name [0]'"对于

{
  "Name": "testuser1",
  "Username": "testuser1",
  "Url": "www.test1.com"
}

当我运行上面的命令时,我收到以下错误。

jq: error (at <stdin>:1): Cannot index string with number

我想为每个对象运行一个forloop。

3 个答案:

答案 0 :(得分:1)

您需要做两件事:一,使用Name选项,以便每个单独的对象成为单个数组的元素。第二,您尝试索引Name,而不是访问数组元素的$ jq -sr '.[].Name' tmp.json testuser1 testuser2 属性。

$ jq -sr '.[1].Name' tmp.json
testuser2

如果您想引用流的特定元素,您可以:

while IFS= read -r name; do
    ...
done < <(jq -sr '.[].Name' tmp.json)

有了这个(假设你的名字都不包含换行符),一个合适的循环看起来像

from("direct:greet")
      .autoStartup(true)
      .routeId("greet")
      .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
      .to("http4://services.groupkt.com/country/get/all")

答案 1 :(得分:0)

要仅选择名字,您需要在之前进行索引尝试进入Name元素:

jq -rs '.[0].Name'

相比之下,对于循环,while read方法given by @chepner's answer确实合适。

答案 2 :(得分:0)

jq是面向流的,所以如果你想对每个对象执行一些操作,那么在jq中定义那个操作就足够了,让jq处理这个流而不用多说。

如果由于某种原因需要流中每个项目的索引,那么如果你的jq有-s,你可以避免使用inputs选项(和jq 1.5一样)。 (避免-s选项可以节省内存。)

以下假设您的jq确实有inputs;索引是从0开始的;并使用-n选项调用jq。

生成索引

foreach inputs as $input (-1; .+1; [., $input])

这将生成[INDEX,ITEM]数组流。然后,您可以使用jq的管道运算符(|)来进一步处理jq过滤器。

从JSON实体流中选择第i个项目。

为了说明调用jq的合适方法,我们假设JSON实体流来自curl COMMAND,我们想要第二个项目(即索引为1)。

调用

curl COMMAND | jq --argjson i 1 -n -f program.jq

(注意-n命令行选项!)

program.jq

def get($i):
  label $done
  | foreach inputs as $input (-1; .+1;
      if $i == . then $input, break $done else empty end);

get($i)