【问题标题】:get the first (or n'th) element in a jq json parsing获取 jq json 解析中的第一个(或第 n 个)元素
【发布时间】: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 的数组是从零开始的。

标签: json jq


【解决方案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]取第一个元素

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 2014-05-03
      • 2010-10-16
      • 2022-01-20
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      相关资源
      最近更新 更多