我希望解析一个JSON文件并提取一些值,同时如果某些条目包含作为参数传入的另一个列表中的子字符串,则丢弃或跳过这些条目.其目的是从主列表中排除包含各种人类可读关键字的对象.
Input.json
{
"entities": [
{
"id": 600,
"name": "foo-001"
},
{
"id": 601,
"name": "foo-002"
},
{
"id": 602,
"name": "foobar-001"
}
]
}
Args.json(关键字列表)
"foobar-"
"BANANA"
输出必须包含foo-*
个条目(但不包含排除的foobar-
个条目),但也可以包含任何其他名称,前提是它们不包含foobar-
或BANANA
.排除将基于子字符串,而不是完全匹配.
我正在寻找一种更好的方式来做这件事,因为目前我只做我的正常过滤器:
jq '[.[].entities[] | select(.name != "")] | walk(if type == "string" then gsub ("\t";"") else . end)' > file
(输入文件中有一些错误的制表符转义和经过预处理的空字段)
在这个阶段,文件只做了最低限度的准备.然后,我在Shell中逐行迭代该文件,并使用关键字文件中的一长串无效模式调用grep -vf
.这提供了一个"主列表",该列表经过清理,以便稍后由其他应用程序进行解析.不过,这似乎在直觉上是错误的.
这似乎应该在第一次与JQ的传球中一举完成,而不是在以后的循环中蛮横地强迫它.
我try 了INDEX
和--slurpfile
的各种调用,但我似乎遗漏了一些东西:
jq '.entities | INDEX(.name)[inputs]' Input.json args.json
上面是一种简单的索引输入参数的方法,它至少似乎演示了文件中的模式可以逐字匹配,但没有考虑子字符串(contains
).
jq '.[] | walk(if type == "object" and (.name | contains($args[]))then empty else . end)' --slurpfile args args.json Input.json
这看起来越来越接近这个 idea ,但这里有一些事情是扭曲的.它似乎是在为关键字文件中的参数的每次迭代返回所有输入文件,并为N个参数返回所有输入文件,而不是实际上清空原始输入,只是默默地判断整个文件是否存在单个关键字,然后重新开始.
似乎我需要解开$args[]
并以某种方式将其映射到这里,以便输入文件只迭代一次,为每条记录判断每个关键字,而不是一遍又一遍地判断整个文件.
我发现了一些关于slurpfile是否是绝对必要的相互矛盾的信息,并且不能确定这里的最佳方法是什么.
谢谢.