如何用jq对docker-compose.yaml中服务的volumes按type排序并更新文件?
问题
我的docker-compose文件内容如下:
{ "name": "movies-docker-test", "services": { "movies-rp": { "volumes": [ { "type": "volume", "source": "certs", "target": "/etc/nginx/certs", }, { "type": "bind", "source": "/home/nblanchet/jeudi_infra/kubernetes/okd/movies-docker-test/reverse-proxy/wikibase.conf.template", "target": "/etc/nginx/templates/wikibase.conf.template" } ] } } }
我需要让每个service下的volumes数组按.type字段排序,期望效果如下:
{ "name": "movies-docker-test", "services": { "movies-rp": { "volumes": [ { "type": "bind", "source": "/home/nblanchet/jeudi_infra/kubernetes/okd/movies-docker-test/reverse-proxy/wikibase.conf.template", "target": "/etc/nginx/templates/wikibase.conf.template" }, { "type": "volume", "source": "certs", "target": "/etc/nginx/certs" } ] } } }
我尝试了以下jq命令,但没能实现文件更新:
jq '[.services[].volumes[]?]|sort_by(.type)'
请告诉我如何正确实现排序并更新docker-compose.yaml文件。
解决方案
你之前的jq命令只提取并排序了所有volumes条目,但没有把排序后的结果放回原结构。要实现需求,需要遍历每个service,对其volumes数组排序后替换原数组,同时保留整个文件的结构。
正确的jq命令如下:
jq '.services[] |= (.volumes |= sort_by(.type))' docker-compose.json
这个命令的逻辑:
.services[]:遍历所有service节点|=:将后续操作的结果赋值回原service节点(.volumes |= sort_by(.type)):对当前service的volumes数组按.type字段排序,并用排序后的数组替换原数组
如果要直接更新原文件,可以使用sponge工具(需先安装moreutils包),避免直接重定向导致文件被清空:
jq '.services[] |= (.volumes |= sort_by(.type))' docker-compose.json | sponge docker-compose.json
如果没有sponge,也可以先将结果写入临时文件,再替换原文件:
jq '.services[] |= (.volumes |= sort_by(.type))' docker-compose.json > temp.json && mv temp.json docker-compose.json
内容的提问来源于stack exchange,提问作者Nathanaël Blanchet
相关产品推荐
相关产品推荐

