假设我有这个json
{
"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重新格式化)
{
"digest": "sha256:1ec7631f74a3d6d37bf9194c13854f33315260ae1f27347263dd0a8974ee82bb",
"imageSizeBytes": "513574770",
"layerId": "",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"tag": [
"python-2-toolchain-latest"
],
"timeCreatedMs": "1535447023647",
"timeUploadedMs": "1535447042373"
}
我尝试了各种方法,并被困在如何引用sha256关键信息上。
答案 0 :(得分:1)
可以实现您的目标的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
]
答案 1 :(得分:0)
这是一个简单明了但有效的解决方案:
keys_unsorted[] as $k
| .[$k] as $value
| select($value.tag[0] == "python-2-toolchain-latest")
| {digest: $k} + $value
答案 2 :(得分:0)
这是我的工作。我认为标签数组可以包含多个条目...
.
|to_entries[]
|.key as $k
|.value as $v
|.value.tag[]
|select(.=="python-2-toolchain-latest")
[ { "digest": ($k) }, $v ] | add
看到最高答案后,我更喜欢最后一行:
[ { "digest": ($k) } + $v ]
如果标签可以出现两次,则它将输出相同的记录两次。必须有一个更好的方法来简单地检查tag []数组中是否包含“ python-2-toolchain-latest”。我的jq foo不够强。
答案 3 :(得分:0)
对于那些愿意接受替代方案的人,这是使用基于步行路径的unix实用程序 jtc
可以实现相同的JSON操作:
bash $ <file.json jtc -w'[:]<D>k<tag>l<python-2-toolchain-latest>[-2]' -T'{"digest":{D}",{}}'
{
"digest": "sha256:1ec7631f74a3d6d37bf9194c13854f33315260ae1f27347263dd0a8974ee82bb",
"imageSizeBytes": "513574770",
"layerId": "",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"tag": [
"python-2-toolchain-latest"
],
"timeCreatedMs": "1535447023647",
"timeUploadedMs": "1535447042373"
}
注意:如果下一个词素中的可搜索上下文唯一标识标签,则不需要词素<tag>l
。如果是这样,则可以省略词素
PS>披露:我是jtc
-用于JSON操作的shell cli工具的创建者
答案 4 :(得分:0)
我会用
.
| 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
),管道的每个阶段(即,
|
之间的每个命令都有一个字节流(通常只是文本),如
它的输入和输出;
-使用jq
,每个阶段都有一个 JSON流
值作为其输入和输出。
jq
程序就是.
:
true
,则输出为true
。[ true, 3.1416, "foo" ]
(数组值),则输出是相同的。true
,3.1416
和"foo"
(布尔值,数字和字符串),
那么三个输出将是该布尔值,该数字和该字符串。.
仅代表输入值,在这种情况下为
您在问题中包含的JSON对象。to_entries
:
{
"a": 3.1416,
"b": false
}
变成这样的数组:
[
{
"key": "a",
"value": 3.1416
},
{
"key": "b",
"value": false
}
]
.[]
,这是一个jq
运算符,它将一个JSON值转换为很多:
[ true, 3.1416, "foo" ]
这样的单个JSON数组,则三个输出是
JSON值true
,3.1416
和"foo"
。select(…)
:
true
,3.1416
和"foo"
,select(type == "string")
只有一个输出:字符串"foo"
。select(…)
有两个输入:
{ "key": "sha256:008…", "value": { "imageSizeBytes": … } }
AND { "key" :"sha256:1ec…", "value": { "imageSizeBytes": … } }
。select(…)
内,我使用了一个本身就是jq
管道的子表达式:.value.tag | contains(["python-2-toolchain-latest"])
:
.value.tag
在每个对象中产生带有键"tag"
的字段的值。为您
示例数据,每个值都是一个JSON数组。contains([…])
中的所有值,则true
部分的值将为[…]
的输入JSON数组值
是该输入JSON数组值的成员。
$ 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
select(…)
中的表达式对于每个具有
具有JSON子对象值的名为true
的密钥,具有JSON数组值的名为"value"
的密钥
包含具有JSON字符串值“ python-2-toolchain-latest”的元素。"tag"
内的表达式为select(…)
的每个输入,该输入值将成为输出值之一。true
。{ "key": "sha256:1ec…", "value": { … } }
表达式,它看起来像一个JSON对象。
jq
说,对于每个输入值,输出具有以下内容的JSON对象值:
{ digest: .key }
的键 AND "digest"
的输入JSON对象的键相关联的值。"key"
,因此这将为我们提供输出JSON
对象{ "key": "sha256:1ec…", … }
。{ "digest": "sha256:1ec…" }
。我们通过添加"value"
来实现。+ .value
jq
运算符与JSON对象值一起使用时,会将其操作数JSON对象“合并”为一个输出JSON对象,
例如+
产生{ "a": true } + { "b": 3.1416 }
。