如何处理split生成的数组子元素?Docker容器数据格式化
问题描述
我正在解析docker container ls --format json的输出,目前用以下jq命令完成了初步处理:
/usr/bin/docker container ls --format json | jq ". | select(.Labels | split(\",\") | index(\"com.docker.compose.project=$1\")) | { id: .ID, ports: .Ports | split(\",\"), labels: .Labels | split(\",\") }" | jq -cs
已经得到包含id、ports数组、labels数组的JSON结构,但还需要实现两个操作:
- 处理
ports数组:去除每个元素的空格,筛选出带映射关系的端口,生成类似{ "8080": "8500", "11112": "11112" }的端口映射对象; - 处理
labels数组:将每个键值对字符串转换为类似{ "com.docker.compose.oneoff": "False", "com.docker.compose.project": "dcm4chee-arc" }的标签映射对象。
解决方案
完全可以实现,你可以将两次jq调用合并为一次,同时完成端口和标签的转换逻辑,最终命令如下:
/usr/bin/docker container ls --format json | jq --arg project "$1" ' select(.Labels | split(",") | index("com.docker.compose.project=\($project)")) | { id: .ID, ports: ( .Ports | split(",") | map(ltrimstr(" ") | rtrimstr(" ")) | map(select(test("->"))) | map(split("->") | [last | split("/")[0], first | split(":")[1]]) | from_entries ), labels: ( .Labels | split(",") | map(ltrimstr(" ") | rtrimstr(" ")) | map(split("=") | {(first): last}) | add ) } ' | jq -cs
端口处理细节
map(ltrimstr(" ") | rtrimstr(" ")):清除端口字符串前后的空格;map(select(test("->"))):仅保留包含映射关系(带->)的端口条目;map(split("->") | [last | split("/")[0], first | split(":")[1]]):拆分映射字符串,提取容器端口(去掉协议部分)和主机端口(去掉IP部分),生成["容器端口", "主机端口"]的键值对数组;from_entries:将键值对数组转换为目标格式的对象。
标签处理细节
map(ltrimstr(" ") | rtrimstr(" ")):清除标签字符串前后的空格;map(split("=") | {(first): last}):将每个key=value格式的字符串转换为单个键值对对象;add:将所有单个键值对对象合并为一个完整的标签对象。
内容的提问来源于stack exchange,提问作者ixM
相关产品推荐
相关产品推荐

