使用jq匹配字段名称的模式

man*_*anu 10 regex json key match 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]
    }
}
Run Code Online (Sandbox Code Playgroud)

我想提取"name"与某个模式匹配的数据中的字段值.例如,我想提取所有不区分大小写的"汉堡"的巧合

[1,2,3],[α,α,3]

我的猜测是这样的

jq '.data | match("what a burger";"i")'
Run Code Online (Sandbox Code Playgroud)

但这会导致

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

干杯.

koa*_*alo 9

您的语句不起作用,因为您尝试将数据对象提供给匹配,但匹配只能用于字符串.

以下表达式将执行您想要的操作.在to_entries将对象转换为键和值的阵列.然后我们通过使用map和(现在是一个字符串)具有的select所有条目迭代这个数组.最后,我们只打印出每个元素的值..keymatch

.data | to_entries | map(select(.key | match("what a burger";"i"))) | map(.value)
Run Code Online (Sandbox Code Playgroud)

但是,两条评论:

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

  • 两个`map`调用可以并且应该组合在一起. (3认同)

pea*_*eak 9

这是一个稍微简短的替代方案:

.data | with_entries(select(.key|match("what a burger";"i")))[]
Run Code Online (Sandbox Code Playgroud)

在纠正输入并使用jq的-c选项后,这将生成两行:

[1,2,3]
["a","a",3]
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个,并帮助我找出所有 key:values 如果键包含模式(或 uniq)对于所有键名为“keynameSOMETHING”的值`.data | with_entries(select(.key|match("keyname+";"ig")))[]` 对于具有相同文件管理器的 key:value,我们只需删除最后的 [] ......如果我想搜索,甚至可以工作键名中有多个 PATTERN,例如:`.data | with_entries(select(.key|match("contains1+", "contains2+"; "ig")))` 没有你的建议是无法做到的,尽管@peak 所以谢谢 (2认同)