jq - 在多个级别上应用过滤器
Posted
技术标签:
【中文标题】jq - 在多个级别上应用过滤器【英文标题】:jq - apply a filter on multiple levels 【发布时间】:2015-05-13 10:36:17 【问题描述】:我有一个这样的 json 文件
"log":
"version":
"$t": "1.1"
,
"creator":
"name":
"$t": "Internet Explorer Network Inspector"
,
"version":
"$t": "10.0.9200.17229"
我需要将文件展平,以便它可以读取
"log":
"version": "1.1",
"creator":
"name": "Internet Explorer Network Inspector",
"version": "10.0.9200.17229"
我知道过滤器 "version": .version ."$t"
将单个元素 "version": "$t": "10.0.9200.17229"
减少到 "version": "10.0.9200.17229"
,但是这个过滤器应该递归地应用于任何级别的任何元素。
【问题讨论】:
【参考方案1】:您可以通过定义新函数来创建递归过滤器:
def untag: (objects | ."$t")
// (objects | with_entries(.value |= untag))
// (arrays | map(untag))
// .
;
untag
所以给定这样的输入:
"log":
"version":
"$t": "1.1"
,
"creator":
"name":
"$t": "Internet Explorer Network Inspector"
,
"version":
"$t": "10.0.9200.17229"
你会回来的:
"log":
"creator":
"name": "Internet Explorer Network Inspector",
"version": "10.0.9200.17229"
,
"version": "1.1"
【讨论】:
所以解释一下。我们定义了一个函数untag
,它选择作为对象的输入,如果它们有$t
,则提取值否则使用来自untag
的值更新对象的值(这是递归部分)。最后,如果我们没有任何$t
,该函数将返回输入本身。
如果你有数组,我已经添加了一些来处理数组。并且不需要对 $t
属性的初始检查。我以为它会抛出一个错误,但它不会。
谢谢杰夫,我正在编辑答案以添加数组处理。希望我注意到 *** 顶部栏上的红色警报;-) 这样做的原因是将 IE 中的 NetworkData.xml
转换为 HAR 格式。我发现xml2json 的第一个 XML > JSON 工具非常冗长,因此我需要将结果展平。确实还有一步,将page
和entries
中的对象转换为普通数组,但这应该很简单......
untag
函数放在哪里?它是如何从命令行调用的?我正在尝试使用 some_command | xml2json | jq
和 untag
进行类似的操作。
@jwfearn 只需调用它。 ... | jq 'untag'
【参考方案2】:
如果你的jq有walk
,你可以如下使用它,如果没有,你可以很容易地google它的def并通过剪切和粘贴的方式包含它:
walk( if type=="object" and has("$t")
then .["$t"] else . end )
【讨论】:
【参考方案3】:扩展 @JeffMercado 的出色回答:
问题
您有一些生成 JSON 的命令,其中字符串值表示如下
"some key": "$t": "some string value"
并且您希望将其转换为如下所示:
"some key": "some string value"
解决方案
把它放在你的~/.jq
文件中:
def untag: (objects | ."$t")
// (objects | with_entries(.value |= untag))
// (arrays | map(untag))
// .
;
像这样使用它:
some_command | jq untag
例子:
$ echo '"some key": "$t": "some string value"' | jq
"some key":
"$t": "some string value"
$ echo '"some key": "$t": "some string value"' | jq untag
"some key": "some string value"
【讨论】:
以上是关于jq - 在多个级别上应用过滤器的主要内容,如果未能解决你的问题,请参考以下文章