'jq wildcard as object in getpath split
Given a basic json
{ 
    "notKnown": { 
        "alpha" : {
            "hello":"world"
        }
    } 
}
and then using getpath with a wildcard as an object does not seem to work
//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
Is there a way to have the format in myPath accept the wildcard as an object in the passed $str path?
Solution 1:[1]
getpath doesn't take some query, but a list of keys.
You are effectively calling
getpath( [ "notKnown[]", "hello" ] )
This is equivalent to
.[ "notKnown[]" ][ "hello" ]
You could use
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 on jqplay
Solution 2:[2]
is there a way to have the format in myPath accept the wildcard as an object in the passed $str path?
Don't think there is a way to let getPath deal with filters like
.[].alpha.hello
However, you can use the myPath variable as the raw filter itself to get the desired output:
$ myPath=".[].alpha.hello"
$ jq -r --arg str "${myPath}" "$myPath" json.json
world
Solution 3:[3]
Undeleting this due to @Peak's comment
getpath expects an array with just the keys, so we'll need the following to find the value:
getpath([ "notKnown", "alpha", "hello"  ])
So to get that using an arg, we can use your split command, but we'll need to remove the . and [] from the myPath var:
myPath="notKnown.alpha.hello"
jq -r --arg str "${myPath}" 'getpath($str|split("."))' json.json
Local shell demo:
$ jq . json.json
{
  "notKnown": {
    "alpha": {
      "hello": "world"
    }
  }
}
$
$ myPath="notKnown.alpha.hello"
$
$ jq -r --arg str "${myPath}" 'getpath($str|split("."))' json.json
world
$
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | ikegami | 
| Solution 2 | 0stone0 | 
| Solution 3 | 
