简体   繁体   English

使用 jq 根据位于 json 文件深处的键搜索值

[英]Using jq to search for a value based on a key located deep in json file

I am new to jq and I'm trying to use it to search for a value in a json file based on a key that is located deep in the json structure.我是 jq 的新手,我正在尝试使用它根据位于 json 结构深处的键在 json 文件中搜索值。 Here is a sample of my json file:这是我的 json 文件的示例:

{
  "data": {
    "inventory": {
      "location": "remote",
      "list": {
        "content": [
          {
            "item": {
              "name": "minivan"
            },
            "owner": {
              "id": "12345",
              "state": "CA"
            }
          },
          {
            "item": {
              "name": "sedan"
            },
            "owner": {
              "id": "67890",
              "state": "AZ"
            }
          }
        ]
      }
    }
  }
}

An example of search that I'm trying to do is:我尝试做的搜索示例是:

select item.name where owner.id = "67890"

and the expected output would be:预期的 output 将是:

item.name = "sedan"

I'm trying to run the following:我正在尝试运行以下命令:

jq '.[] | select .owner.id = "67890" | .item.name' json

and it generates an error:它会产生一个错误:

jq: error: select/0 is not defined at <top-level>, line 1:
.[] | select .owner.id = "67890" | .item.name      
jq: 1 compile error

Any pointers on how to do this in jq would be much appreciated!非常感谢任何有关如何在 jq 中执行此操作的指示! Thanks!谢谢!

First, you have to "navigate" to where you want to make the query.首先,您必须“导航”到要进行查询的位置。 This seems to be an array.这似乎是一个数组。

.data.inventory.list.content
[
  {
    "item": {
      "name": "minivan"
    },
    "owner": {
      "id": "12345",
      "state": "CA"
    }
  },
  {
    "item": {
      "name": "sedan"
    },
    "owner": {
      "id": "67890",
      "state": "AZ"
    }
  }
]

Demo演示

Next, let's iterate over that array's items, which gives us a stream of objects.接下来,让我们迭代该数组的项目,这为我们提供了 stream 个对象。

.[]
{
  "item": {
    "name": "minivan"
  },
  "owner": {
    "id": "12345",
    "state": "CA"
  }
}
{
  "item": {
    "name": "sedan"
  },
  "owner": {
    "id": "67890",
    "state": "AZ"
  }
}

Demo演示

From these objects we select those that match your criteria.从这些对象中,我们 select 符合您的标准。

select(.owner.id == "67890")
{
  "item": {
    "name": "sedan"
  },
  "owner": {
    "id": "67890",
    "state": "AZ"
  }
}

Demo演示

Finally, we extract the value you're interested in.最后,我们提取您感兴趣的值。

.item.name
"sedan"

Demo演示

Everything combined in a jq call would be: jq 调用中组合的所有内容将是:

jq '.data.inventory.list.content[] | select(.owner.id == "67890").item.name'
"sedan"

Demo演示

This output is still valid JSON document (containing nothing but a JSON string).这个 output 仍然是有效的 JSON 文档(只包含一个 JSON 字符串)。 If you want to process the output as raw text, use the --raw-output (or -r ) option:如果要将 output 作为原始文本处理,请使用--raw-output (或-r )选项:

jq -r '.data.inventory.list.content[] | select(.owner.id == "67890").item.name'
sedan

Demo演示

Here's a solution that avoids having to "navigate" to the right place, and which is also quite close to your SQL-like query:这是一个避免必须“导航”到正确位置的解决方案,并且它也非常接近您的类似 SQL 的查询:

..
| objects 
| select(.owner and 
         (.owner|type=="object" and .id == "67890"))
  .item.name

or more succinctly:或更简洁:

..|objects|select(.owner.id? == "67890").item.name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM