2017-02-05 144 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],[A,A,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将对象转换为一个键和值的数组。然后我们通过使用mapselect迭代这个数组,其中.key(现在是字符串)的所有条目都有match。最后我们打印出每个元素的值。

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

然而,两点意见:

  • [a,a,3]不JSON不允许的,因为a不是数字。
  • 它的作用是因为键实际上是不同的,即使只有字母大小写不相等。如果至少两个密钥相同,则会遇到问题,因为密钥应该是唯一的。实际上,jq只会输出其中一个元素。
+1

两个'map'电话可以并且应该合并。 –

5

这里有一个稍微简短的选择:

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

整流输入,并使用JQ的-c选项之后,这将产生两行:

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

我喜欢这个,并帮助我找出所有关键值:如果关键字包含一个模板(或者是uniq) 对于关键字名称为“keynameSOMETHING”的所有值 '.data | with_entries(选择(.key | match(“keyname +”;“ig”)))[]' 对于key:具有相同filer的值,我们只在最后删除[],甚至在我想要在键名中搜索多个PATTERN: '.data | with_entries(选择(.key | match(“contains1 +”,“contains2 +”;“ig”)))' 不能做到这一点没有你的建议,尽管@peak所以谢谢 – Mikec