使用jq基于对象中变量的值选择对象

Dan*_*iel 202 bash json jq

我有以下json文件:

{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Whereever"
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用jq并希望得到'location'为'Stockholm'的对象的"名称"元素.

我知道我可以得到所有的名字

cat json | jq .[] | jq ."name"
"Jack"
"Walt"
"Donald"
Run Code Online (Sandbox Code Playgroud)

但考虑到子键的值(这里"location" : "Stockholm"),我无法弄清楚如何只打印某些对象.

Dan*_*iel 281

经过大量谷歌搜索主要发现jQuery的东西后,我发现了一篇博文,其中包含答案:

$ jq '.[] | select(.location=="Stockholm")' json
{
  "location": "Stockholm",
  "name": "Walt"
}
{
  "location": "Stockholm",
  "name": "Donald"
}
Run Code Online (Sandbox Code Playgroud)

从这里:http://zerokspot.com/weblog/2013/07/18/processing-json-with-jq/

  • 如何获得父母'FOO','BAR','BAZ'? (22认同)

pea*_*eak 152

要获得只有名称的流:

$ jq '.[] | select(.location=="Stockholm") | .name' json
Run Code Online (Sandbox Code Playgroud)

生产:

"Donald"
"Walt"
Run Code Online (Sandbox Code Playgroud)

要获取相应的(键名称,"名称"属性)对的流,请考虑:

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

输出:

["FOO","Donald"]
["BAR","Walt"]
Run Code Online (Sandbox Code Playgroud)

  • 我不确定其他答案是如何领先于这一个的. (9认同)
  • 他想要基于位置的整个对象:“给定子键的值,我无法弄清楚如何仅打印某些对象” (2认同)
  • 选择后不需要管道:$ jq'。[] | select(.location ==“ Stockholm”)。name'json (2认同)

spa*_*azm 24

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

Jq提供to_entriesfrom_entries在对象和键值对数组之间进行转换.那与map选择周围一起

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

from_entries执行相反的转换,with_entries(foo)是to_entries |的简写 map(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"
  }
}
Run Code Online (Sandbox Code Playgroud)

使用with_entries速记,这变为:

jq15 < json 'with_entries(select(.value.location=="Stockholm"))'
{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 一直困扰着我的一件事是你需要记住,当使用 `with_entries()` 时,你通常还想在 `select` 子句中使用 `.value`。这是因为 `to_entries` 宏将给定的条目转换为 `.key` 和 `.value` 对,这也发生在 `with_entries` 中。 (3认同)

Yor*_*iev 14

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

# create the example file to  be working on .. 
cat << EOF > tmp.json
[  
 { "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


# pass the content of the file to the  jq query, which gets the array of objects
# and 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
jq -r '.[]| select (.card_id_type == "card_id_type-01")|.card_id' <tmp.json
id-01
Run Code Online (Sandbox Code Playgroud)

或使用 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
Run Code Online (Sandbox Code Playgroud)

  • 检查您的个人设置以对答案进行排序...它可能基于上次修改的 ts ;o) (2认同)