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

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

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

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

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

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

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

Ответ 1

После того, как много поисковых систем в поисках 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/

Ответ 2

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

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

дает:

"Donald"
"Walt"

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

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

Вывод:

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

Ответ 3

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

Jq предоставляет to_entries и from_entries для преобразования между объектами и массивами пар ключ-значение. Это вместе с map вокруг выбора

Эти функции преобразуют между объектом и массивом значений ключа пар. Если to_entries передается объект, то для каждой записи k: v в вход, выходной массив включает { "ключ": k, "значение": 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"
  }
}

Используя сокращение with_entries, это будет:

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