JSON key-globbing - PullRequest
       14

JSON key-globbing

0 голосов
/ 08 мая 2018

На странице справочника jq есть несколько примеров форматирования вывода, в частности, некоторые ярлыки, когда вы хотите просто повторить то, что было во входном JSON.

Что если я хочу точно отобразить то, что было на входе, но только для клавиш, которые соответствуют определенному шаблону?

Например, при заданном входе вот так ...

[
{"Name":"Widgets","Size":10,"SymUS":"Widg","SymCN":"Zyin","SymJP":"Kono"},
{"Name":"Blodgets","Size":400,"SymUS":"Blodg","SymAU":"Blod","SymJP":"Kado"},
{"Name":"Fonzes","Size":11,"SymRU":"Fyet","SymBR":"Foao"}
]

Скажем, я хочу выбрать все объекты, где Name оканчивается на "ets", а затем отобразить Name и все атрибуты формы Sym*. Все, что я знаю об этих атрибутах, - это то, что для каждого объекта JSON будет один или несколько, а имена имеют формат Sym, за которым следует двухбуквенный код страны ISO.

Я хотел бы просто сделать это:

jq '.[] | select(.Name | endswith("ets")) | {Name, Sym*}'

но это не вещь.

Разве это не то, что jq предназначено для обработки за одну операцию? Должен ли я сделать первый проход через файл, чтобы собрать все возможные ключи, а затем перечислить их все явно через slurpfile?

1 Ответ

0 голосов
/ 08 мая 2018

Ключ к простому решению проблемы - to_entries, как описано в онлайн-руководстве. С вашими примерами следующий фильтр производит вывод, показанный ниже, в соответствии с тем, что я понимаю под ожиданиями:

.[]
| select(.Name | test("ets$"))
| {Name} + (to_entries | map(select(.key|test("^Sym"))) | from_entries)

Возможно, вы захотите усовершенствовать тесты регулярных выражений и / или внести другие незначительные корректировки.

Выход:

{
  "Name": "Widgets",
  "SymUS": "Widg",
  "SymCN": "Zyin",
  "SymJP": "Kono"
}
{
  "Name": "Blodgets",
  "SymUS": "Blodg",
  "SymAU": "Blod",
  "SymJP": "Kado"
}
...