jq以递归方式删除模式

时间:2017-11-09 14:55:35

标签: arrays json sed jq recursive-datastructures

我试图找出如何使用jq删除数组中架构中任何位置发生的特定值。

在这种情况下,我试图从标有代理的字段下面的数组内的任何位置删除agent4。

这是我到目前为止所拥有的

jq '..|.agents? | select(. != null) |  map(select(. != "agent4"))'

但这只会创建已更改的数据,而我也不知道如何将其重新分配到路径中。

我最初尝试使用sed,但它绝对不是使用的工具所以我切换到jq。

   {
      "environments": {
        "default": {
          "machines": {
            "dev-machine": {
              "agents": [
                "agent1",
                "agent2",
                "agent3",
                "agent4"
              ]
            }
          }
        }
      },
      "environments2": {         
         "agents": [
            "agent1",
            "agent2",
            "agent3",
            "agent4"
         ] 
      }
    }

然而,这只是输出

[
  "agent1",
  "agent2",
  "agent3"
]
[
  "agent1",
  "agent2",
  "agent3"
]

2 个答案:

答案 0 :(得分:0)

以下是使用path查找“agent4”并在使用delpaths

删除之前验证它是否显示在“代理”中的解决方案
delpaths([ path(..|select(.=="agent4")) | select(.[-2]=="agents") ])

示例运行(假设data.json中的数据)

$ jq -M 'delpaths([ path(..|select(.=="agent4")) | select(.[-2]=="agents") ])' data.json
{
  "environments": {
    "default": {
      "machines": {
        "dev-machine": {
          "agents": [
            "agent1",
            "agent2",
            "agent3"
          ]
        }
      }
    }
  },
  "environments2": {
    "agents": [
      "agent1",
      "agent2",
      "agent3"
    ]
  }
}

Try it online at jqplay.org

以下是使用reduceleaf_pathsgetpathdelpaths的另一种方式:

reduce leaf_paths as $p (.;
  if $p[-2]=="agents" and getpath($p)=="agent4" then delpaths([$p]) else . end
)

Try it online at jqplay.org

答案 1 :(得分:0)

以下是使用from bokeh.io import show, output_file from bokeh.models import HoverTool from bokeh.plotting import figure from bokeh.sampledata.autompg import autompg as df output_file("groupby.html") df.cyl = df.cyl.astype(str) group = df.groupby('cyl') p = figure(plot_height=350, x_range=group, toolbar_location=None, tools="") p.vbar(x='cyl', top='mpg_mean', width=0.9, source=group) p.add_tools(HoverTool(tooltips=[("Avg MPG", "@mpg_mean")])) show(p) 的解决方案:

walk

如果要从所有数组中删除值,无论它们出现在何处:

walk( if type == "object" and has("agents") 
      then .agents |= map(select(. != "agent4"))
      else . end )

如果您想要更灵活的解决方案,例如,您可以将walk( if type == "array" then map(select(. != "agent4")) else . end ) 替换为"agent4",然后在命令行上设置$value,例如如果VALUE是字符串,则使用$value,或者--arg value VALUE。{/ p>

如果您的jq没有--argjson value VALUE,只需在其https://github.com/stedolan/jq/blob/master/src/builtin.jq

之前添加其定义(例如)