我想在 JSON 文件的任何级别(我事先不知道确切的树)找到一个特定值(不用担心键)并显示父键。
我已经提取了这个样本:
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
}
]
}
]
}
我可以使用此递归命令找到字符串“CREDENTIALS_VAULT-1212121212121”:
cat /tmp/test.json | jq '.auditLogs[] | .. | .credentialId? | select(. == "CREDENTIALS_VAULT-1212121212121")'
"CREDENTIALS_VAULT-1212121212121"
但我还想在第一级获取父键“logId”。我尝试使用变量($parent),但不幸的是我得到了几个结果而不是只有一个:
cat /tmp/test.json | jq '.auditLogs[] as $parent | .. | .credentialId? | select(. == "CREDENTIALS_VAULT-1212121212121") | $parent | {"logId":.logId}'
{
"logId": "169807591200060002"
}
{
"logId": "169807591200060001"
}
有人对这个需求有想法吗?
您可以使用
paths
查找具有匹配值的路径,从中提取前两项(在本例中为 ["auditLogs",0]
),使用 getpath
检索该对象,然后从那里提取 .logId
:
jq -r 'getpath(paths(. == "CREDENTIALS_VAULT-1212121212121")[:2]).logId'
169807591200060002
如果您想要仅包含
logId
字段的对象,请使用 {logId}
代替:
jq 'getpath(paths(. == "CREDENTIALS_VAULT-1212121212121")[:2]) | {logId}'
{
"logId": "169807591200060002"
}
您还可以考虑通过将
[…]
包裹在过滤器周围来将结果收集到数组中。或者使用 --arg
选项从命令行导入搜索键等
IN
(或 any(stream; condition)
):
.auditLogs[]
| select(IN(.. | .credentialId?; "CREDENTIALS_VAULT-1212121212121"))
| .logId
或者,根据您的输出格式要求:
.auditLogs[]
| select(IN(.. | .credentialId?; "CREDENTIALS_VAULT-1212121212121"))
| { logId }