jq:如何切割嵌套对象以包含父键层次结构?

时间:2018-05-20 15:35:29

标签: json bash nested jq

使用Bash和jq,如果我有一个形式为.<key1>.<key2>...<keyN>的Bash变量过滤器 F ,我想切片一个Bash变量JSON对象 O 所以结果只是对象的一部分,包括 F 中的所有键,如何用jq完成?

例如,假设:

O='
{
   "a":
   {
      "b":
      {
         "c": { "p":1 },
         "x": 1
      },
      "x": 2
  },
  "x": 3
}'

然后,做:

F='.a.b.c'; jq -r "$F" <<<"$O"

结果:

{
   "p": 1
}

但是,我希望切片包含父键层次结构。

不雅的解决方案

我提出了一个解决方案,但它涉及到对jq的两次调用:

F='.a.b.c'; S="$(jq -r "$F" <<<"$O"); jq --null-input -r "$F |= $S"

导致:

{
  "a": {
    "b": {
      "c": {
        "p": 1
      }
    }
  }
}

该解决方案必须适用于 任何 有效的 O F Bash变量 O 存储JSON对象, F 是一个简单的键名过滤器,仅如上所述。例如:

F='.a.b'; S="$(jq -r "$F" <<<"$O")"; jq --null-input -r "$F |= $S"

结果:

{
  "a": {
    "b": {
      "c": {
        "p": 1
      },
      "x": 1
    }
  }
}

可以在jq中更简单地使用键层次结构过滤器切片对象吗?

1 个答案:

答案 0 :(得分:2)

提供$ F是一个有效的jq路径表达式(即,jq -n "$F"有效):

jq "$F as \$v | null | $F |= \$v" <<< "$O"

(我在你的解决方案中包含了| =来显示相似性,但在这里你可以删除|。)