'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 |