获取 jq json 解析中的第一个(或第 n 个)元素

Posted

技术标签:

【中文标题】获取 jq json 解析中的第一个(或第 n 个)元素【英文标题】:get the first (or n'th) element in a jq json parsing 【发布时间】:2016-11-24 19:37:39 【问题描述】:

我可以在 [] 内的 json 中获取第一个元素

$ echo '["a":"x", "b":true, "a":"XML", "b":false]' | jq '.[1]'

  "a": "XML",
  "b": false

但是如果json已经被反汇编了(例如,在使用'select'过滤条目之后),我怎样才能选择单个条目并避免这里看到的错误?

$ echo '["a":"x", "b":true, "a":"x", "b":false,"a":"XML", "b":false]' | jq '.[] | select( .a == "x")'

  "a": "x",
  "b": true


  "a": "x",
  "b": false

$ echo '["a":"x", "b":true, "a":"x", "b":false,"a":"XML", "b":false]' | jq '.[] | select( .a == "x") | .[1]'
jq: error (at <stdin>:1): Cannot index object with number

【问题讨论】:

'.[1]' 实际上得到了第二个元素。 '.[0]' 会让你第一个。 javascript 的数组是从零开始的。 【参考方案1】:

您可以将来自select 的结果包装在一个数组中:

jq '[.[]|select(.a=="x")][0]' your.json

输出:


  "a": "x",
  "b": false

【讨论】:

【参考方案2】:

jq 还提供了first/0last/0nth/1 所以在这种情况下过滤器

  ( map(select(.a == "x")) | first  )
, ( map(select(.a == "x")) | last   ) 
, ( map(select(.a == "x")) | nth(1) )

生产


  "a": "x",
  "b": true


  "a": "x",
  "b": false


  "a": "x",
  "b": false

还可以使用其他流形式 'first/1'、'last/1' 和 'nth/2',以便使用此数据

  ( first(.[]  | select(.a == "x")) )   
, ( last(.[]   | select(.a == "x")) )
, ( nth(1; .[] | select(.a == "x")) )

生产


  "a": "x",
  "b": true


  "a": "x",
  "b": false


  "a": "x",
  "b": false

【讨论】:

整洁。我如何也可以执行 jq 请求来检索条目数? 建议使用 length 内置函数或 reduce .[] as $x (0;.+1)【参考方案3】:

之前的许多答案都是通过避免首先创建对象流来工作的。但是,如果您开始使用对象流(例如 JSON 格式的应用程序日志)怎么办?如果您的输入文件(或流)中有多个对象,则从独立对象流中选择单个条目所需要做的就是使用--slurp 选项(或缩写为-s):

   o   --slurp/-s:

       Instead of running the filter for each JSON object in the input, read 
       the entire input stream into a large array and run the filter just once.

然后你可以索引到数组中。例如,要获取第二项(索引为 1):

jq --slurp '.[1]'

将它与您想要从流中选择该项目的原始问题放在一起:

echo '"a":"x", "b":true "a":"XML", "b":false' | jq --slurp '.[1]'

导致此输出:


  "a": "XML",
  "b": false

【讨论】:

谢谢,所有其他答案都产生了jq: error (at &lt;stdin&gt;:1): Cannot index object with number 的一些变化,但这就像一个魅力。【参考方案4】:

使用map

cat raw.json|jq -r -c 'map(select(.a=="x"))|.[1]'

map 接收 filter 来过滤数组。

这个命令

cat raw.json|jq -r -c 'map(select(.a=="x"))'

给出中间结果

["a":"x","b":true,"a":"x","b":false]

.[1]取第一个元素

【讨论】:

以上是关于获取 jq json 解析中的第一个(或第 n 个)元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 jq 从多维 JSON 数组中选择第 n 个元素

如何使用 jq (或其他替代方法)解析 JSON 字符串?

通过JQ和BASH / SHELL获取JSON文档的第三个元素

UITableView 中的第二个视图不会显示来自 JSON 的解析数据

Linux 命令详解Shell 解析 json命令jq详解

如何删除 jq 输出中的双引号以在 bash 中解析 json 文件?