使用 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 将对象转换为键和值的数组。然后我们使用mapselect 遍历这个数组,其中.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 模式匹配字段名称的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 sql 中按匹配某些模式的字段进行分组?

材质 UI 文本字段模式匹配

如何阻止创建名称与特定模式匹配的 MySQL 数据库

sed / awk - 使用模式匹配后插入空格

在bash中将文本附加到具有模式匹配名称的文件[重复]

如何使用模式匹配器仅获取与 Java 中正则表达式匹配的第一行?