使用 jq 按名称访问数组列表项

Access array list item by name using jq

提问人:Kris 提问时间:11/13/2023 更新时间:11/14/2023 访问量:49

问:

请考虑以下 json 数据,该数据来自 Docker 映像:nginx:1.25-bookworm

# docker pull nginx:1.25-bookworm
# docker image inspect 81be38025439 | jq '.[].Config.Env'
[
  "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  "NGINX_VERSION=1.25.3",
  "NJS_VERSION=0.8.2",
  "PKG_RELEASE=1~bookworm"
]
#

我希望能够从此列表中访问“1.25.3”,以在 CI-CD 管道的构建步骤中标记映像。

我通过以下几点接近我的目标:

# docker image inspect 0743972990c7 | jq -r '.[].Config.Env[1]'
NGINX_VERSION=1.23.4

但是想知道如何按名称访问项目“NGINX_VERSION”,而不是依赖于它将是第二个环境变量的假设。

docker 持续集成 jq

评论


答:

3赞 KamilCuk 11/13/2023 #1

因此,从数组中过滤NGINX_VERSION并将其删除。

.[].Config.Env |
select(startswith("NGINX_VERSION=")) |
sub("^NGINX_VERSION="; "")
3赞 pmf 11/13/2023 #2

对于给定的任务,我也会按照 KamilCuk 的回答中的描述去做。但是,如果您需要访问多个值,您可能需要考虑使用以下命令创建查找对象:startswithINDEX

INDEX(.[:index("=")]) as $ix   # stores {"PATH": … , "NGINX_VERSION": … , …}

然后按字段名称访问值(按第一个字符的位置截断):index=

| $ix["NGINX_VERSION"]         # yields "NGINX_VERSION=1.25.3"
| .[index("=")+1:]             # yields "1.25.3

演示

1赞 peak 11/14/2023 #3

下面是一个有用的函数,用于将表单的字符串数组转换为 JSON 对象:key<DELIM>value

# input: an array of strings of the form: key + delim + value
# It is assumed that delim is string with a single character that 
# is not special in the context of regular expressions.
def toObject(delim): 
  map( capture("(?<key>[^" + delim + "]*)" + delim + "(?<value>.*)" )) | from_entries;

然后,所述问题的解决方案可以写成:

toObject("=") | .NGINX_VERSION