使用 jq 模式匹配字段名称
Posted
技术标签:
【中文标题】使用 jq 模式匹配字段名称【英文标题】:Pattern matching field names with jq 【发布时间】:2017-06-22 10:32:53 【问题描述】:这是一个非常基本(可能很愚蠢)的问题,但我无法解决...
我有一个具有这种结构的 JSON 文件:
"data":
"what a burger": [1,2,3],
"wap": [66],
"the map": [11,20],
"H. Incandenza": [1,1],
"What a burger": [a,a,3]
我想提取 data 中“名称”与特定模式匹配的字段的值。例如,我想提取“what a burger”的所有不区分大小写的巧合来得到
[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
干杯。
【问题讨论】:
【参考方案1】:您的语句不起作用,因为您尝试将数据对象提供给 match,但 match 只能对字符串起作用。
下面的表达式会做你想做的事。 to_entries
将对象转换为键和值的数组。然后我们使用map
和select
遍历这个数组,其中.key
(现在是一个字符串)具有match
的所有条目。最后我们只打印出每个元素的值。
.data | to_entries | map(select(.key | match("what a burger";"i"))) | map(.value)
但是,两个 cmets:
[a,a,3]
不允许在 JSON 中使用,因为 a
不是数字。
它之所以有效,是因为键实际上是不同的,即使只有字母大小写不相等。如果至少有两个键是相同的,你会遇到问题,因为键应该是唯一的。事实上,jq
只会输出其中一个元素。
【讨论】:
两个map
调用可以而且应该合并。【参考方案2】:
这里有一个稍微简短的替代方案:
.data | with_entries(select(.key|match("what a burger";"i")))[]
在纠正输入后,使用 jq 的 -c 选项,这将产生两行:
[1,2,3]
["a","a",3]
【讨论】:
我喜欢这个,并帮助我弄清楚如果键包含模式(或为 uniq),则获取所有键:值 对于键名为“keynameSOMETHING”的所有值.data | with_entries(select(.key|match("keyname+";"ig")))[]
对于键:value 使用相同的文件管理器,我们只是在末尾删除 [] ......如果我想在键名中搜索多个 PATTERN,甚至可以工作,例如:.data | with_entries(select(.key|match("contains1+", "contains2+"; "ig")))
没有你的建议就无法完成@高峰非常感谢以上是关于使用 jq 模式匹配字段名称的主要内容,如果未能解决你的问题,请参考以下文章