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

Dem*_*ait 26 json jq

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

$ echo '[{"a":"x", "b":true}, {"a":"XML", "b":false}]' | jq '.[1]'
{
  "a": "XML",
  "b": false
}
Run Code Online (Sandbox Code Playgroud)

但是如果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
Run Code Online (Sandbox Code Playgroud)

hek*_*mgl 32

您可以将结果包装select在数组中:

jq '[.[]|select(.a=="x")][0]' your.json
Run Code Online (Sandbox Code Playgroud)

输出:

{
  "a": "x",
  "b": false
}
Run Code Online (Sandbox Code Playgroud)


jq1*_*727 10

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

  ( map(select(.a == "x")) | first  )
, ( map(select(.a == "x")) | last   ) 
, ( map(select(.a == "x")) | nth(1) )
Run Code Online (Sandbox Code Playgroud)

产生

{
  "a": "x",
  "b": true
}
{
  "a": "x",
  "b": false
}
{
  "a": "x",
  "b": false
}
Run Code Online (Sandbox Code Playgroud)

其他流式表格'first/1','last/1''nth/2'也可以使用这些数据

  ( first(.[]  | select(.a == "x")) )   
, ( last(.[]   | select(.a == "x")) )
, ( nth(1; .[] | select(.a == "x")) )
Run Code Online (Sandbox Code Playgroud)

产生

{
  "a": "x",
  "b": true
}
{
  "a": "x",
  "b": false
}
{
  "a": "x",
  "b": false
}
Run Code Online (Sandbox Code Playgroud)


tin*_*ink 6

map

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

map接收一个过滤器来过滤一个数组。

这个命令

cat raw.json|jq -r -c 'map(select(.a=="x"))'
Run Code Online (Sandbox Code Playgroud)

给出中间结果

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

.[1] 取第一个元素


jby*_*ler 5

以前的许多答案都是通过首先避免创建对象流来工作的。但是,如果您对象流(例如 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.
Run Code Online (Sandbox Code Playgroud)

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

jq --slurp '.[1]'
Run Code Online (Sandbox Code Playgroud)

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

echo '{"a":"x", "b":true} {"a":"XML", "b":false}' | jq --slurp '.[1]'
Run Code Online (Sandbox Code Playgroud)

这导致此输出:

{
  "a": "XML",
  "b": false
}
Run Code Online (Sandbox Code Playgroud)