Выберите объекты на основе значения переменной в объекте, используя jq

У меня есть следующий файл JSON:

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

Я использую jq и хочу получить элементы "name" для объектов, где "location" - "Stockholm".

Я знаю, что могу получить все имена

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

Но я не могу понять, как печатать только определенные объекты, учитывая значение дополнительного ключа (здесь "location" : "Stockholm").

5 ответов

Решение

После множества поисков в основном в jQuery я нашел сообщение в блоге с ответом:

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

Отсюда: http://zerokspot.com/weblog/2013/07/18/processing-json-with-jq/

Чтобы получить поток только имен:

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

производит:

"Donald"
"Walt"

Чтобы получить поток соответствующих пар (имя ключа, атрибут "имя"), рассмотрим:

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

Выход:

["FOO","Donald"]
["BAR","Walt"]

У меня был похожий вопрос: что если вы хотите вернуть исходный формат объекта (с именами ключей, например, FOO, BAR)?

JQ обеспечивает to_entries а также from_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"
  }
}

Просто попробуйте это как полную копию пасты в оболочке, и вы поймете это

# 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


# pipe the content of the file to the  jq query, which gets the array of objects
# and select the attribute named "card_id" ONLY if it's 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 tmp.json | jq -r '.[]| select (.card_id_type == "card_id_type-01")|.card_id'

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

Надеюсь, это поможет другим, я использовал jq в сотнях своих собственных скриптов, но каждый раз борюсь с использованием в нем переменных... в этом случае ниже был единственный способ передать ему число var (т. е. одинарные кавычки) вокруг arg/var):

      id=26533

cat mydata.json | jq -r --arg id "$id" '.sensor[] |
select(.objid=='$id').probe'
Другие вопросы по тегам