Input json is:
[
{
"id": "00001",
"profile": {
"extensions": [
{
"name": "/somepath1...../AAAAAA"
},
{
"name": "/somepath2...../xxxxxx"
}
]
}
},
{
"id": "00002",
"profile": {
"extensions": [
{
"name": "/somepath1...../zzzzzz"
},
{
"name": "/somepath2...../BBBBBB"
}
]
}
},
{
"id": "00003",
"profile": {
"extensions": [
{
"name": "/somepath1...../yyyyyy"
}
]
}
},
{
"id": "00004",
"profile": {
"extensions": []
}
}
]
I need to find id of object having .profile.extensions[].name having values containing string AAAAAA or BBBBBB.
Expected output for above json example would be:
00001 AAAAAA
00002 BBBBBB
Because in the first one the is AAAAAA and in second BBBBBB
CodePudding user response:
You are probably looking for this filter pattern, which iterates over the array elements .[], filters for matching items using select and outputs the field id as raw text due to the -r flag.
jq -r '.[] | select( … ).id'
What the expression within your select filter should be, depends on how you define "having values containing [a] string".
If the search string has to match the last part of a slash-delimited list of substrings (as your sample data might suggest), you could split up the target string using / (or split), extract the last item and use IN to apply the test to a stream of search strings. (Demo)
IN(.profile.extensions[].name / "/" | last; "AAAAAA", "BBBBBB")
If the slashes should not be considered specially (i.e. a search string could also contain slashes) and if a search string simply appearing at the end of the target string is a match, then you can use endswith to test it and any to prevent multiple matches for the same id if several names within the same iterated object end with a given search string. (Demo)
[.profile.extensions[].name | endswith("AAAAAA", "BBBBBB")] | any
If, however, the search string is allowed to appear anywhere in the name, just change endswith to contains. (Demo)
[.profile.extensions[].name | contains("AAAAAA", "BBBBBB")] | any
Regarding your update which altered the output to include the matching search string, and your additional comment stating that the target string is indeed a slash-separated list, the approach now is as follows:
In order to test and output the search string, i.e. to use and to reference it again, we need to store it in a variable (using $s here), which has to happen outside the select filter in order to have its scope reach until the output reference.
jq -r '.[] | ("AAAAAA", "BBBBBB") as $s
| select(IN(.profile.extensions[].name / "/" | last; $s))
| "\(.id) \($s)"
'
00001 AAAAAA
00002 BBBBBB
