Выберите объекты на основе значения переменной в объекте, используя 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'