Json 在数组或对象中选择
鉴于这三份文件 一个具有语句对象:Json 在数组或对象中选择,json,types,filtering,jq,jtc,Json,Types,Filtering,Jq,Jtc,鉴于这三份文件 一个具有语句对象: { "PolicyVersion": { "CreateDate": "2017-07-13T18:59:21Z", "VersionId": "v2", "Document": { "Version": "2012-10-17", "Statement": { "Action": "*",
{
"PolicyVersion": {
"CreateDate": "2017-07-13T18:59:21Z",
"VersionId": "v2",
"Document": {
"Version": "2012-10-17",
"Statement": {
"Action": "*",
"Resource": "*",
"Effect": "Allow"
}
},
"IsDefaultVersion": true
}
}
…和一个带有语句数组的:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
…和一个嵌套在完整文档中的语句:
{
"PolicyVersion": {
"CreateDate": "2017-07-13T18:59:21Z",
"VersionId": "v2",
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "*",
"Resource": "*",
"Effect": "Allow"
}
]
},
"IsDefaultVersion": true
}
}
当.Action='*'和.Resource=='*'存在于语句中时,是否可以使用单个命令来选择它是数组、对象还是嵌套在何处
例如,我扫描了数千个文档,其中唯一的区别是语句可能是对象或数组
当然,类似于:jq'.PolicyVersion.Document.Statement[]| select.Action=*和.Resource==*的内容适用于数组,而jq'.PolicyVersion.Document.Statement | select.Action=*和.Resource=*适用于非数组的情况,但我希望通过一个命令实现这一点
我在select附近尝试了一些方法,例如:
jq'.PolicyVersion.Document | select.Statement[]| select.Action==*和.Resource==*或select.Statement[]| select.Action=*和.Resource==*'
不返回任何内容,并且:
jq'.PolicyVersion.Document | select.Statement[]| select.Action==*和.Resource==*或select.Statement | select.Action=*和.Resource==*'
返回一个unix shell引用错误。以下内容可能比您需要的更通用,或者可能太通用,请随意品尝:
..
| objects
| select(.Statement)
| .Statement
| if type == "array" then .[] else . end
| select(.Action == "*" and .Resource == "*")
以下内容可能比您需要的更普通,也可能太普通,所以请随意品尝:
..
| objects
| select(.Statement)
| .Statement
| if type == "array" then .[] else . end
| select(.Action == "*" and .Resource == "*")
另一种方法非常适合这种特殊情况:
.PolicyVersion.Document.Statement
| ..
| select(type == "object" and .Action == "*" and .Resource == "*")
另一种方法非常适合这种特殊情况:
.PolicyVersion.Document.Statement
| ..
| select(type == "object" and .Action == "*" and .Resource == "*")
在OP的许可下,让我在这里演示如何使用walk path unix实用程序实现相同的JSON查询。但是,我将演示如何构建步行路径,而不是解释步行路径 我对这个问题的理解是:验证JSON文档,这样,如果文档中的任何地方有一个包含元素Action:*和Resource:*的标签语句条目,那么就打印包含这些元素的整个记录,否则就不会留下空白输出 一,。让我们从使用label语句递归查找JSON条目开始递归搜索的符号是,后缀l指示只搜索标签,因此它可以位于JSON文档中的任何位置我将使用第一个JSON示例:
bash $ <file.json jtc -w'<Statement>l'
[
{
"Action": "*",
"Effect": "Allow",
"Resource": "*"
}
]
bash $
三,。现在我们需要查看是否有兄弟资源:*到找到的条目。为此,让我们在JSON树a.k.a地址父级中提升一个级别:
bash $ <file.json jtc -w'<Statement>l[Action]:<*>[-1]'
{
"Action": "*",
"Effect": "Allow",
"Resource": "*"
}
bash $
最后,jtc从文件而不是stdin中读取时速度要快几倍,出于性能原因,最好将其作为参数传递文件:
jtc -w'<Statement>l[Action]:<*>[-1][Resource]:>*<[-1]' file.json
PS>我是unix实用程序JSON处理的创建者在OP的许可下,让我在这里演示如何使用walk path unix实用程序实现相同的JSON查询。但是,我将演示如何构建步行路径,而不是解释步行路径 我对这个问题的理解是:验证JSON文档,这样,如果文档中的任何地方有一个包含元素Action:*和Resource:*的标签语句条目,那么就打印包含这些元素的整个记录,否则就不会留下空白输出 一,。让我们从使用label语句递归查找JSON条目开始递归搜索的符号是,后缀l指示只搜索标签,因此它可以位于JSON文档中的任何位置我将使用第一个JSON示例:
bash $ <file.json jtc -w'<Statement>l'
[
{
"Action": "*",
"Effect": "Allow",
"Resource": "*"
}
]
bash $
三,。现在我们需要查看是否有兄弟资源:*到找到的条目。为此,让我们在JSON树a.k.a地址父级中提升一个级别:
bash $ <file.json jtc -w'<Statement>l[Action]:<*>[-1]'
{
"Action": "*",
"Effect": "Allow",
"Resource": "*"
}
bash $
最后,jtc从文件而不是stdin中读取时速度要快几倍,出于性能原因,最好将其作为参数传递文件:
jtc -w'<Statement>l[Action]:<*>[-1][Resource]:>*<[-1]' file.json
PS>我是unix实用程序JSON处理的创建者,非常有用,谢谢。在我完成添加用例示例之前,我已经更新了发布的问题。这可能是另一个问题,但如果语句位于文档根目录下,并且没有嵌套,我希望也能起作用。@try再次参考peak的答案,这确实有效,谢谢。在我完成添加用例示例之前,我已经更新了发布的问题。这可能是另一个问题,但如果语句位于文档根目录下,并且不是嵌套的,我希望也能实现这一点。@请尝试再次参考peak的答案,非常好,谢谢!适用于我能想到/看到的所有用例,包括我在最后一篇文章中提到的三个用例。如果可以,你介意详细说明这是如何工作的吗?再次感谢:太棒了,谢谢!适用于我能想到/看到的所有用例,包括我在最后一篇文章中提到的三个用例。如果可以,你介意详细说明这是如何工作的吗?再次感谢:出于您的考虑,同样的JSON查询也可以使用另一个unix漫游路径实用程序来实现。jtc:感谢您传播知识,@Dmitry:Always
顺便说一句,在上面的示例中,选择了整个文档,我可能误解了这个问题,在下面的回答中,我将详细说明如何仅选择包含操作和资源的语句中的记录(如果两者都是*)。让我知道ask是否有不同的含义。我还发现了一个使用jmespath的lambda函数,该函数使用以下方法实现:if jmespath.search'PolicyVersion.Document.Statement[?Effect=\'Allow\'&&containsResource,\'*\'&&contains Action,\'*\'],policy_version:我想在这里分享另一种可能的方法/解决方案。出于您的考虑,同样的JSON查询可以使用另一种unix漫游路径实用程序实现。jtc:感谢您传播知识,@Dmitry:始终欣赏其他方法并学习不同的方法。顺便说一句,在上面的示例中,选择了整个文档,我可能误解了这个问题,在下面的回答中,我将详细说明如何在语句中仅选择包含Action和Resource的记录(如果两者都是*)。让我知道ask是否有不同的含义。我还发现了一个使用jmespath的lambda函数,它使用以下方法实现:如果jmespath.search'PolicyVersion.Document.Statement[?Effect=\'Allow\'&&containsResource,\'*\'&&contains Action,\'*\'],策略版本:我想在这里分享另一种可能的方法/解决方案。