364

我有以下 json 文件:

{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Whereever"
    }
}

我正在使用 jq 并希望获取“位置”为“斯德哥尔摩”的对象的“名称”元素。

我知道我可以通过

cat json | jq .[] | jq ."name"
"Jack"
"Walt"
"Donald"

但是我不知道如何只打印某些对象,给定子键的值(这里:)"location" : "Stockholm"

4

4 回答 4

534

改编自使用 jq 处理 JSON的这篇文章,您可以select(bool)这样使用:

$ jq '.[] | select(.location=="Stockholm")' json
{
  "location": "Stockholm",
  "name": "Walt"
}
{
  "location": "Stockholm",
  "name": "Donald"
}
于 2013-09-04T07:42:01.470 回答
250

要获取仅包含名称的流:

$ jq '.[] | select(.location=="Stockholm") | .name' json

产生:

"Donald"
"Walt"

要获得对应的(键名,“名称”属性)对流,请考虑:

$ jq -c 'to_entries[]
        | select (.value.location == "Stockholm")
        | [.key, .value.name]' json

输出:

["FOO","Donald"]
["BAR","Walt"]
于 2015-08-10T04:50:15.597 回答
48

我有一个类似的相关问题:如果您想要返回原始对象格式(带有键名,例如 FOO、BAR)怎么办?

Jq 提供对象to_entriesfrom_entries键值对数组之间的转换。那连同map周围的选择

这些函数在对象和键值对数组之间进行转换。如果向 to_entries 传递了一个对象,那么对于输入中的每个 k:v 条目,输出数组包括 {"key":k, "value":v}。

from_entries 进行相反的转换,with_entries(foo) 是 to_entries | 的简写。地图(foo) | from_entries,用于对对象的所有键和值进行一些操作。from_entries 接受键、键、名称、名称、值和值作为键。

jq15 < json 'to_entries | map(select(.value.location=="Stockholm")) | from_entries'

{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

使用with_entries速记,这变成:

jq15 < json 'with_entries(select(.value.location=="Stockholm"))'
{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}
于 2016-06-15T19:06:28.277 回答
20

只需尝试将其作为 shell 中的完整复制粘贴,您就会掌握它。

# pass the multiline string to the jq, use the jq to 
# select the attribute named "card_id" 
# ONLY if its neighbour attribute
# named "card_id_type" has the "card_id_type-01" value.
# jq -r means give me ONLY the value of the jq query no quotes aka raw


cat << EOF | \
    jq -r '.[]| select (.card_id_type == "card_id_type-01")|.card_id'
    [  
     { "card_id": "id-00", "card_id_type": "card_id_type-00"},
     { "card_id": "id-01", "card_id_type": "card_id_type-01"},
     { "card_id": "id-02", "card_id_type": "card_id_type-02"}
    ]
EOF
# this ^^^ MUST start first on the line - no whitespace there !!!
# outputs:
# id-01

或使用 aws cli 命令

 # list my vpcs or
 # list the values of the tags which names are "Name" 
 aws ec2 describe-vpcs | jq -r '.| .Vpcs[].Tags[]
        |select (.Key == "Name") | .Value'|sort  -nr

请注意,您可以在过滤阶段和选择阶段在层次结构中上下移动:

 kubectl get services --all-namespaces -o json | jq -r '
 .items[] | select( .metadata.name 
     | contains("my-srch-string")) | 
     { name: .metadata.name, ns: .metadata.namespace 
     , nodePort: .spec.ports[].nodePort
     , port: .spec.ports[].port}
 '
于 2020-10-05T16:00:28.600 回答