如何使用'jq'按嵌套值过滤此json并打印父密钥标识符?
假设我有这个json如何使用'jq'按嵌套值过滤此json并打印父密钥标识符?,json,jq,Json,Jq,假设我有这个json { "sha256:0085b5379bf1baeb4a430128782440fe636938aa739f6a5ecc4152a22f19b08b": { "imageSizeBytes": "596515805", "layerId": "", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "tag": [ "python-3-to
{
"sha256:0085b5379bf1baeb4a430128782440fe636938aa739f6a5ecc4152a22f19b08b": {
"imageSizeBytes": "596515805",
"layerId": "",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"tag": [
"python-3-toolchain-0.1.2"
],
"timeCreatedMs": "1564631021992",
"timeUploadedMs": "1564631067325"
},
"sha256:1ec7631f74a3d6d37bf9194c13854f33315260ae1f27347263dd0a8974ee82bb": {
"imageSizeBytes": "513574770",
"layerId": "",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"tag": [
"python-2-toolchain-latest"
],
"timeCreatedMs": "1535447023647",
"timeUploadedMs": "1535447042373"
}
}
我想选择带有特定标记的图像信息(以及sha256摘要)。示例:我只想选择tag==“python-2-toolchain-latest”
,所以它会打印这个json(使用json格式)
我已经尝试过各种方法,并且一直在研究如何引用sha256关键信息 这里有一个简单明了但高效的解决方案:
keys_unsorted[] as $k
| .[$k] as $value
| select($value.tag[0] == "python-2-toolchain-latest")
| {digest: $k} + $value
这是我的想法。我假设标记数组可以包含多个条目
.
|to_entries[]
|.key as $k
|.value as $v
|.value.tag[]
|select(.=="python-2-toolchain-latest")
[ { "digest": ($k) }, $v ] | add
看到峰值答案后,我更喜欢最后一行:
[ { "digest": ($k) } + $v ]
如果标记可以出现两次,那么将输出相同的记录两次。必须有更好的方法来简单地检查标记[]数组中是否有“python-2-toolchain-latest”。我的jq-foo不够强大。一个可能的
jq
计划来实现您的目标:
# Embed the final result into an array to get a valid JSON output
[
# Convert the input object into a list of { key, value } objects
to_entries[]
# Keep only the objects that contain the desired tag
# The .tag field may contain multiple tags and the desired one can be at any position
| select(.value.tag | contains(["python-2-toolchain-latest"]))
# Add the key into the value object into the .digest property
| .value.digest = .key
# Keep only the values (the modified objects)
| .value
# That's all, folks
]
我会用
.
| to_entries
| .[]
| select(.value.tag | contains(["python-2-toolchain-latest"]))
| { digest: .key } + .value
- 我将您的示例数据放在一个名为
的文件中pratama-1.json
- 我运行了下面的命令并得到了这个输出。
$ jq '. | to_entries | .[] | select(.value.tag | contains(["python-2-toolchain-latest"])) | { digest: .key } + .value' pratama-1.json { "digest": "sha256:1ec7631f74a3d6d37bf9194c13854f33315260ae1f27347263dd0a8974ee82bb", "imageSizeBytes": "513574770", "layerId": "", "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "tag": [ "python-2-toolchain-latest" ], "timeCreatedMs": "1535447023647", "timeUploadedMs": "1535447042373" }
jq
程序视为类似于sh
管道,
除:
-使用sh
(或bash
),管道的每个阶段(即,
|
s)之间的每个命令都有一个字节流(通常只是文本),如下所示:
投入产出;
-使用jq
,每个阶段都有一个JSON流
值作为其输入和输出
jq
程序就是
:
- 如果输入是JSON值
,则输出是true
true
- 如果输入是JSON值
(数组值),则输出相同[true,3.1416,“foo”]
- 如果输入是三个JSON值
、true
和3.1416
(布尔值、数字和字符串), 然后这三个输出将是布尔值、数字和字符串“foo”
仅表示输入值,在本例中为
您在问题中包含的JSON对象到\u条目
:
- 它将JSON对象转换为JSON对象的JSON数组。对于输入,例如:
进入如下数组:{ "a": 3.1416, "b": false }
[ { "key": "a", "value": 3.1416 }, { "key": "b", "value": false } ]
[]
,它是一个jq
操作符,可以将一个JSON值转换为多个:
- 如果输入是一个JSON数组,如
,则三个输出是 JSON值为[true,3.1416,“foo”]
,true
,以及3.1416
“foo”
- 在我们的例子中,它打开了所有键值对象周围的JSON数组,这样我们就可以 输出值,而不是一个JSON数组输出值
选择(…)
:
- 对于每个输入值,它计算括号中的表达式并“传递”该输入 如果表达式为true,则作为输出
- 例如,对于三个输入
、true
和3.1416
,“foo”
只有一个输出:字符串选择(type==“string”)
“foo”
- 我的
有两个输入:select(…)
- JSON对象
和{“key”:“sha256:008…”,“value”:{“imageSizeBytes”:…}
- JSON对象
{“key”:“sha256:1ec…”,“value”:{“imageSizeBytes”:…}
select(…)
中,我使用了一个本身是jq
管道的子表达式:.value.tag | contains([“python-2-toolchain-latest”])
:
.value.tag
在每个对象中生成键为“tag”
的字段值。为了你的
示例数据中,每个值都是一个JSON数组包含([…])
如果其参数JSON-array[…])
是该输入JSON数组值的成员。
- 一些例子
$jq'包含([“foo”])@AgungPratama-这只是四行代码,所以如果您使用jq手册阅读未排序的键、as
、选择,以及对象添加(+
)。@peak我喜欢您的解决方案,但它只找到“python…”
数组中索引0
处的对象。另外,我喜欢to_entries
来获取键值对。@ColinFraizer-如果想要所有匹配项,只需省略0
!FWIW,我选择了keys\u unsorted
,因为这会产生(稍微)更有效的解决方案。@peak谢谢!我并没有真正考虑使用<代码>选择($Value.tag)=“Python 2-TooChan-NeXT”<<代码>。它是有效的,但我很难把我的头围绕着它。它看起来像一个有两个操作数的运算符,但我想不是。
[
{
"key": "a",
"value": 3.1416
},
{
"key": "b",
"value": false
}
]
$ jq '. | contains([ "foo" ])' <<< '[ true, 3.1416, "foo" ]'
true
$ jq '. | contains([ "foo", true ])' <<< '[ true, 3.1416, "foo" ]'
true
$ jq '. | contains([ "foo", true, null ])' <<< '[ true, 3.1416, "foo" ]'
false
$ jq '. | contains([ "foo", true, false ])' <<< '[ true, 3.1416, "foo" ]'
false
$ jq '. | contains([ "foo", true, null ])' <<< '[ true, 3.1416, "foo" ]'
false