jq 通配符作为 getpath split 中的对象

jq wildcard as object in getpath split

给定一个基础json

{ 
    "notKnown": { 
        "alpha" : {
            "hello":"world"
        }
    } 
}

然后使用带有通配符的 getpath 作为对象似乎不起作用

//Eg 1 - complete string generates correct result
myPath="notKnown.alpha.hello"
output=$(jq -r --arg str "${myPath}" 'getpath($str|split("."))' <<<$myJson) 
>> output="world"   

//Eg 2 - test the wildcard directly generates correct result
output=$(jq -r '.notKnown[].hello' <<<$myJson) 
>> output="world"

//Eg 3 - merge the wildcard into the formatting from Eg1 - generates null
myPath="notKnown[].hello"
output=$(jq -r --arg str "${myPath}" 'getpath($str|split("."))' <<<$myJson) 
>> output=null

//Eg 4 - merge the wildcard into the formatting from Eg1 - generates null
different example strings that generate null (assuming the first dot should not be used)
 myPath="[].alpha.hello"
 myPath=".[].alpha.hello" //leading dot expect fail
 myPath="[]alpha.hello"
 myPath=".[]alpha.hello"   //leading dot expect fail 

output=$(jq -r --arg str "${myPath}" 'getpath($str|split("."))' <<<$myJson)
>> output=null

有没有办法让 myPath 中的格式接受通配符作为传递的 $str 路径中的对象?

由于@Peak 的

取消删除

getpath 需要一个仅包含键的数组,因此我们需要以下内容来查找值:

getpath([ "notKnown", "alpha", "hello"  ])

因此,要使用 arg 获得它,我们可以使用您的 split 命令,但我们需要从 myPath 中删除 .[]变量:

myPath="notKnown.alpha.hello"
jq -r --arg str "${myPath}" 'getpath($str|split("."))' json.json

本地 shell 演示:

$ jq . json.json
{
  "notKnown": {
    "alpha": {
      "hello": "world"
    }
  }
}
$
$ myPath="notKnown.alpha.hello"
$
$ jq -r --arg str "${myPath}" 'getpath($str|split("."))' json.json
world
$

is there a way to have the format in myPath accept the wildcard as an object in the passed $str path?

不认为有办法让 getPath 处理像这样的过滤器 .[].alpha.hello


但是,您可以使用 myPath 变量作为 raw 过滤器本身来获得所需的输出:

$ myPath=".[].alpha.hello"
$ jq -r --arg str "${myPath}" "$myPath" json.json
world

getpath 不接受一些查询,而是一个键列表。

您实际上是在调用

getpath( [ "notKnown[]", "hello" ] )

这相当于

.[ "notKnown[]" ][ "hello" ]

你可以使用

def _simple_query( $q ):
   if $q | length == 0 then
      .
   else
      $q[0] as $key |
      $q[1:] as $r |
      if $key == "*" then
         .[] | _simple_query( $r )
      else
         select( has( $key ) ) | .[ $key ] | _simple_query( $r )
      end
   end;

def simple_query( $q ):
   _simple_query( $q | split(".") );

simple_query( "*.alpha.hello" )

Demo 在 jqplay