I have exported bookmarks from Firefox which in my case is quiet large JSON. I'm interested in the object with guid _0no-4e9woLW
in a JSON such as this one:
{
"foo": {
"bar": {
"zoo": {
"guid": "_0no-4e9woLW",
"title": "frontend",
"index": 3,
"dateAdded": 1614198626454000,
"lastModified": 1619505016472000,
"id": 16518,
"typeCode": 2,
"type": "text/x-moz-place-container",
"children": [
{
"guid": "2L7ZsYTM2RX0",
"title": "css child override parent style",
"index": 0,
"dateAdded": 1614198648005000,
"lastModified": 1614198648005000,
"id": 16519,
"typeCode": 1,
"type": "text/x-moz-place",
"uri": "https://www.google.com/search?client=firefox-b-d&q=css child override parent style"
},
{
"guid": "x3JHTAezzyI8",
"title": "css child parent inheritance",
"index": 1,
"dateAdded": 1614198648096000,
"lastModified": 1614198648096000,
"id": 16520,
"typeCode": 1,
"type": "text/x-moz-place",
"uri": "https://www.google.com/search?client=firefox-b-d&q=css child parent inheritance"
}
]
}
}
}
}
Is it possible to get somehow full path up to "guid": "_0no-4e9woLW"
? guid keys are uniq in JSON. My goal is to type something like jq '["full path I've somehow previously obtained"]["children"].title'
And I will obtain:
css child override parent style
css child parent inheritance
Of course I could do this manually but I'm too lazy.
CodePudding user response:
Without the whole knowledge of the JSON, something like this should work when using path
family of functions i.e. getpath/1
( paths | select(.[-1] == "guid") ) as $p |
if getpath($p) == "_0no-4e9woLW" then getpath($p[:-1] ["children"])[].title else empty end
The construct above means, select all those paths containing the leaf key named guid
and store them in a variable and filter only the path whose value turns out to be "_0no-4e9woLW"
. On the selected path, trim the child node($p[:-1]
removes "guid"
) and add the node "children"
and get the value at the new path constructed (using getpath/1
). Extract the .title
field from the JSON value
CodePudding user response:
Using recurse
allows to get to the object easily :
jq -r 'recurse |
select(type=="object" and .guid == "_0no-4e9woLW")
.children[].title' firefox.json
CodePudding user response:
To access a node by guid:
.. | objects | select( .guid == … )
So you'd use the following to get the title of
_0no-4e9woLW
's children:.. | objects | select( .guid == "_0no-4e9woLW" ) | .children[].title
To save a path:
path( … ) # As JSON
path( … ) | join(".") # As dotted path
Replace
…
with an expression that returns the node(s) for which you want the path.For example,
path( .. | objects | select( .guid == "_0no-4e9woLW" ) ) # [ "foo", "bar", "zoo" ]
path( .. | objects | select( .guid == "_0no-4e9woLW" ) ) | join(".") # "foo.bar.zoo"
To grab an object using its path:
getpath( … ) # From JSON
getpath( … | split(".") | map(tonumber? // .) ) # From dotted path
Replace
…
with an expression that returns the previously saved path.For example,
getpath( [ "foo", "bar", "zoo" ] ).children[].title
getpath( "foo.bar.zoo" | split(".") | map(tonumber? // .) ).children[].title