2017-02-05 18 views
5

это очень простой (возможно глупый) вопрос, но я не могу заставить его работать ...шаблон соответствия имен полей с JQ

У меня есть файл в формате JSON с этой структурой

{                                                            
    "data": { 
     "what a burger": [1,2,3], 
     "wap": [66], 
     "the map": [11,20], 
     "H. Incandenza": [1,1], 
     "What a burger": [a,a,3] 
    } 
} 

и я хотел бы извлечь значения полей в пределах данных, чье «имя» соответствует определенному шаблону. Например, я хотел бы, чтобы извлечь все регистронезависимых совпадения «что гамбургер», чтобы получить

[1,2,3], [а, а, 3]

Мое предположение было бы что-то как

jq '.data | match("what a burger";"i")' 

, но это приводит к

jq: error (at <stdin>:9): object ({"what a bu...) cannot be matched, as it is not a string 

Приветствия.

ответ

2

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

Следующее выражение будет делать то, что вы хотите. to_entries преобразует объект в массив ключей и значений. Затем мы перебираем этот массив, используя map и select все записи, где .key (теперь строка) имеет match. Наконец, мы просто распечатываем значение каждого элемента.

.data | to_entries | map(select(.key | match("what a burger";"i"))) | map(.value) 

Однако два комментария:

  • [a,a,3] не допускается в формате JSON, потому что a не является числом.
  • Это работает, потому что клавиши ARE действительно разные, даже если только случай с буквой не равен. Если хотя бы два ключа идентичны, вы столкнетесь с проблемами, потому что ключи должны быть уникальными. Фактически, jq будет выводить только один из элементов.
+1

Два 'map' звонки может и должен сочетаться. –

5

Вот несколько краток альтернатива:

.data | with_entries(select(.key|match("what a burger";"i")))[] 

После устранения вход, и используя опцию -c JQ, это будет производить две линии:

[1,2,3] 
["a","a",3] 
+0

Мне это нравится, и мне помогли выяснить все ключи: значения, если ключ содержит patern (или uniq) Для всех значений, где ключевое имя «keynameSOMETHING» '.data | with_entries (select (.key | match ("keyname +"; "ig"))) [] ' Для ключа: значение с тем же фильтром мы просто удаляем [] в конце ... и даже работаем, если я хочу для поиска более одного PATTERN в ключевом названии типа: '.data | with_entries (выберите (.key | match ("contains1 +", "contains2 +"; "ig"))) ' не удалось сделать это без вашего предложения, хотя @peak так спасибо – Mikec