From jq's Types And Values Documentation:
Object Construction
The value can be any expression (although you may need to wrap it in parentheses if, for example, it contains colons), which gets applied to the
{}
expression's input (remember, all filters have an input and an output).
{foo: .bar}
[ ... ]
Because that is so common, there's a shortcut syntax for it:
{user, title}
.
So given the following example json
{
"foo": {
"bar": {
"value": 42,
"valid": true
},
"valid": false
},
"valid": false
}
If I only want the complete foo
object (removing the outer valid
key), I can get the desired output by using
{ foo }
Unfortunately, the documentation doesn't mention any way to get the same behaviour, but for deeper keys, using the example above, getting an output object with just the .foo.bar
object would look something like:
{ "foo": { "bar": .foo.bar } }
Which will generate the following (desired) json output:
{
"foo": {
"bar": {
"value": 42,
"valid": true
}
}
}
Note both the outer valid
and the .foo.valid
are missing.
Is there any short-cut alternative for the above selector to get the same result?
Ideally I'd use something like:
{ foo.bar }
CodePudding user response:
Not exactly a short-cut alternative, but the path functions can be used for this. This assumes you know the names of the paths beforehand and know they exist
jq -n 'setpath( ["foo", "bar"] ; ( inputs | getpath(["foo", "bar"]) ) )'
The setpath/2
function sets the value on the assigned path indicated in the first argument. The value for the path is set from the original input using getpath/1
You could use the --argjson
to pass the path as an array and use it directly as well.
jq -n --argjson p '["foo", "bar"]' 'setpath( $p ; ( inputs | getpath($p) ) )'
CodePudding user response:
Here is (quite literally) a shorter alternative that's also DRYer, though I don't think it's any clearer:
{foo} | .foo |= {bar}