I would like to find in a JSON file a specific value (without worrying about the key) at any level of my JSON file (I don’t know in advance the exact tree) and display the parent keys.
I have extracted this sample :
cat /tmp/test.json | jq
{
"totalCount": 2,
"pageSize": 1000,
"auditLogs": [
{
"logId": "169807591200060002",
"eventType": "CREATE",
"category": "CONFIG",
"entityId": "HTTP_CHECK-12121212121212",
"timestamp": 1698075912003,
"success": true,
"patch": [
{
"op": "replace",
"path": "/",
"value": {
"steps": [
{
"id": {
"type": "HTTP_CHECK_STEP"
},
"requestType": "OAUTH2",
"destinationUrl": "https://www.mywebsite.com",
"httpMethod": "POST",
"acceptAnyCertificate": true,
"followRedirects": true,
"displayName": "My Website",
"userAgent": "",
"httpCheckHeaders": [
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded"
}
],
"stepPerformanceThreshold": 0,
"requestBody": null,
"constraints": [
{
"constraintType": "HttpStatusesList",
"passIfFound": false,
"pattern": ">=400"
}
],
"preScript": "",
"postScript": "",
"attributes": {
"oAuth2RequestId": "1",
"oAuth2BodyInputType": "RAW",
"oAuth2addAuthDataTo": "REQUEST_BODY"
},
"postExecutionScriptVariables": [
"{bearerToken-1}"
],
"preExecutionScriptVariables": [],
"certificateId": "",
"basicAuthId": "",
"certStoreId": 0,
"basicAuthStoreId": 0,
"authenticationConfig": {
"type": "BASIC_AUTHENTICATION",
"realmName": null,
"kdcIp": null,
"credentialId": "CREDENTIALS_VAULT-1212121212121"
},
"executionProperties": {},
"shouldNotPersistSensitiveData": true
}
],
"publicLocationIds": [
124
],
"userModificationTimestamp": 1698075911987,
"customProperties": [],
"version": 6
},
"oldValue": null
}
]
},
{
"logId": "169807591200060001",
"eventType": "CREATE",
"category": "CONFIG",
"entityId": "HTTP_CHECK-12121212121212",
"environmentId": "b416bf43-a9d2-4123-aa70-e36ff39c0ad9",
"timestamp": 1698075911986,
"success": true,
"patch": [
{
"op": "replace",
"path": "/",
"value": {
"frequency (Frequency)": 0,
"locations": [
{
"location (Location)": "SYNTHETIC_LOCATION-000000000000007C"
}
]
},
"oldValue": null
}
]
}
]
}
I am able to find the string "CREDENTIALS_VAULT-1212121212121" with this recursive command :
cat /tmp/test.json | jq '.auditLogs[] | .. | .credentialId? | select(. == "CREDENTIALS_VAULT-1212121212121")'
"CREDENTIALS_VAULT-1212121212121"
But I would like also to get the parent key "logId" at the first level. I tried to use a variable ($parent) but unfortunately I got several results instead of only one :
cat /tmp/test.json | jq '.auditLogs[] as $parent | .. | .credentialId? | select(. == "CREDENTIALS_VAULT-1212121212121") | $parent | {"logId":.logId}'
{
"logId": "169807591200060002"
}
{
"logId": "169807591200060001"
}
Does anyone have an idea for this need?
2
Answers
You could use
paths
to find the paths with matching values, extract from it the first two items (["auditLogs",0]
in this case), usegetpath
to retrieve that object, and extract.logId
from there:Demo
If you want objects containing only the
logId
field, use{logId}
instead:Demo
You can also consider collecting the results in an array by wrapping
[…]
around the filter. Or use the--arg
option to import the search key from the command line, etc.You can use
IN
(orany(stream; condition)
):or, depending on your output format requirements: