首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将多个对象传递给jq进行递归滤波操作

将多个对象传递给jq进行递归滤波操作
EN

Stack Overflow用户
提问于 2015-11-11 17:27:04
回答 3查看 1.2K关注 0票数 1

我试图使用JQ1.5开发一个脚本,它可以接受一个或多个用户输入,这些输入代表一个键,并递归地从JSON输入中删除它们。

我所指的JSON在这里:https://github.com/EmersonElectricCo/fsf/blob/master/docs/Test.json

我的脚本,似乎运行得很好,如下所示。

代码语言:javascript
复制
def post_recurse(f):
   def r:
      (f | select(. != null) | r), .;
      r;
def post_recurse:
   post_recurse(.[]?);
(post_recurse | objects) |= del(.META_BASIC_INFO)

但是,我想用一个或多个用户输入来代替META_BASIC_INFO。我该怎么做才能做到这一点?我猜想--arg来自命令行,但我不清楚如何将它合并到我的.jq脚本中?

我尝试过用del(.$module)代替del(.$module)并调用cat test.json | ./jq -f fsf_key_filter.jq --arg module META_BASIC_INFO来进行测试,但这是行不通的。

任何关于这方面的指导都是非常感谢的!

答:

基于几个建议,我能够到达以下的工作和用户JQ。

见习:

代码语言:javascript
复制
cat test.json | jq --argjson delete '["META_BASIC_INFO","SCAN_YARA"]' -f fsf_module_filter.jq

代码:

代码语言:javascript
复制
def post_recurse(f):
        def r:
                (f | select(. != null) | r), .;
                r;
def post_recurse:
        post_recurse(.[]?);
(post_recurse | objects) |= reduce $delete[] as $d (.; delpaths([[ $d ]]))
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-11 17:40:13

您还可以使用delpath/1。例如:

代码语言:javascript
复制
$ jq -n '{"a":1, "b": 1} | delpaths([["a"]])'
{
  "b": 1
}

也就是说,修改您的程序,使最后一行如下所示:

代码语言:javascript
复制
(post_recurse | objects) |= delpaths([[ $delete ]] )

您将像这样调用jq:

代码语言:javascript
复制
$ jq --arg delete "META_BASIC_INFO" -f delete.jq input.json

(不能使用--arg module ...,因为"$module“具有某种保留状态。)

票数 0
EN

Stack Overflow用户

发布于 2015-11-11 19:53:19

module的名称似乎是1.5中的关键字,因此$module将导致语法错误。你应该换个名字。还有其他构建可以为您进行递归,请考虑使用它们而不是自己的构建。

代码语言:javascript
复制
$ jq '(.. | objects | select(has($a))) |= del(.[$a])' --arg a "META_BASIC_INFO" Test.json
票数 1
EN

Stack Overflow用户

发布于 2015-11-12 04:22:10

下面是使用walk/1的“单行”解决方案:

代码语言:javascript
复制
jq --arg d "META_BASIC_INFO" 'walk(if type == "object" then del(.[$d]) else . end)' input.json

如果步行/1不在您的jq中,下面是它的定义:

代码语言:javascript
复制
# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
    elif type == "array" then map( walk(f) ) | f
    else f
    end;

如果您想递归地删除一组键值对,那么下面是一种使用--argjson的方法

rdelete.jq:

代码语言:javascript
复制
def rdelete(key):
  walk(if type == "object" then del(.[key]) else . end);

reduce $strings[] as $s (.; rdelete($s))

调用:

代码语言:javascript
复制
$ jq --argjson strings '["a","b"]' -f rdelete.jq input.json
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33656260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档