For any JSON object, for example,
{
"Book1": {
"Genres": [
"horror",
"thriller",
"drama"
],
"Description": "Extremely scary book.",
"Author": "Jane Doe"
},
"Book2": {
"Genres": [
"Romance",
"drama"
],
"Description": "Very romantic book.",
"Author": "John Doe"
}
}
Is it possible to do a general search over every single key? For example, if you search for "horror" it would return
{
"Book1": {
"Genres": [
"horror",
"thriller",
"drama"
],
"Description": "Extremely scary book.",
"Author": "Jane Doe"
}
}
as the word is found in the "Genres" or if you search for "romantic" it would return Book2 as the word is contained in the description. I want to avoid having to specify the key in which the value is found in but rather have a general search over the entire object.
CodePudding user response:
Use ..
to traverse the tree, strings
to compare only strings, any
to return true on first match, and map_values
to retain the original tree structure.
jq 'map_values(select(any(..; strings == "horror")))'
{
"Book1": {
"Genres": [
"horror",
"thriller",
"drama"
],
"Description": "Extremely scary book.",
"Author": "Jane Doe"
}
}
To include substrings in the search, use contains
instead:
jq 'map_values(select(any(.. | strings; contains("romantic"))))'
{
"Book2": {
"Genres": [
"Romance",
"drama"
],
"Description": "Very romantic book.",
"Author": "John Doe"
}
}
You may also want to convert to upper or lower case using ascii_upcase
or ascii_downcase
to have a case-insensitive search, or use test
for a regex search.