Выбор объекта JQ без бесконечных цепочек фильтров - PullRequest
0 голосов
/ 02 мая 2018

Мне трудно использовать jq (1.5) для анализа глубоко вложенных структур JSON, и я чувствую, что использую это неправильно. Возьмите этот пример ввода JSON:

{
 "a":[],
 "b":[
  {"x":"bar", "s":"FX", "f":["blorg","blarg","blurb"], "v":true},
  {"x":"bar", "s":"EX", "f":["blorg","blarg","bloob"], "v":false},
  {"x":"bar", "s":"XT", "f":["blorg","blart","bloop"], "v":true},
  {"x":"bar", "s":"IJ", "f":["blorg","bleep","glarp"], "v":true},
  {"x":"foo", "s":"IX", "f":["porg","parg","pork","peep"], "v":true},
  {"x":"baz", "s":"AB", "f":["zing","zang","zoop"], "v":false}
  ],
 "c":[]
}
  • Извлечь объекты из списка b, где x - это "бар", это просто:

    jq '.["b"][] | select(.x == "bar")' < file.json

  • Дальнейшее ограничение на объект с определенным значением s также просто:

    jq '.["b"][] | select(.x == "bar" and .s == "FX")' < file.json

Если я хочу применить тест регулярного выражения или любой другой тест, который требует строкового ввода (учитывая, что мне все еще нужны выходные данные объекта), я думаю, что у меня нет другого выбора, кроме как связывать фильтры. Например ...

  • Чтобы ограничиться объектами, где s оканчивается на "X", к сожалению, в jq нет ничего особенного:

    jq '.["b"][] | select(.x == "bar" and .s.endswith("X"))' < file.json

    Вместо этого я думаю, что должен сделать это:

    jq '.["b"][] | select(.x == "bar") | select(.s | endswith("X"))' < file.json

  • Аналогично s содержит "X":

    jq '.["b"][] | select(.x == "bar") | select(.s | test("X"))' < file.json

Что хорошо, если я всегда делаю логические AND с, но что, если я хочу сделать OR? Например, что это за программа jq для получения объектов, где x означает "бар" OR s оканчивается на "X"? jq имеет |OR| фильтр?

jq '.["b"][] | select(.x == "bar") |OR| select(.s | endswith("X"))' < file.json

Или я просто делаю это неправильно? Пытаюсь ли я изобрести какой-нибудь стандартный jq алгоритм выбора объектов?

1 Ответ

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

Прямо (укажите все ваши условия в функции select):

jq -c '.b[] | select(.x == "bar" or (.s | endswith("X")))' file.json

Выход:

{"x":"bar","s":"FX","f":["blorg","blarg","blurb"],"v":true}
{"x":"bar","s":"EX","f":["blorg","blarg","bloob"],"v":false}
{"x":"bar","s":"XT","f":["blorg","blart","bloop"],"v":true}
{"x":"bar","s":"IJ","f":["blorg","bleep","glarp"],"v":true}
{"x":"foo","s":"IX","f":["porg","parg","pork","peep"],"v":true}
...