使用jq提取AWS监听器数据时如何去除重复输出的ARN值
jq提取AWS ELB配置去重输出方案
问题背景
需求为提取AWS负载均衡监听器的ARN及关联协议、端口信息,要求同一个ARN仅输出一次,后续依次列出该ARN对应的所有端口与协议。
原使用命令:
jq -r '.Listeners[] | (.LoadBalancerArn), (.Protocol)'
原命令输出存在ARN重复打印问题,结果如下:
"arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde" "HTTP" "arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde" "HTTP" "arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde" "HTTPS"
尝试调用unique、first、unique_by、select、contains等函数处理时,均返回Cannot iterate over string或数值类型相关报错。
期望输出格式:
"arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde" "HTTP" "HTTP" "HTTPS"
待处理样例JSON数据:
{ "Listeners": [ { "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde", "Port": 9090, "Protocol": "HTTP" }, { "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde", "Port": 80, "Protocol": "HTTP" }, { "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde", "Port": 443, "Protocol": "HTTPS" } ] }
报错原因
原命令遍历每个监听器对象时,都会同步打印一次当前对象的ARN和协议,最终输出流是交替排列的ARN、协议字符串值。直接对字符串类型的值调用仅支持数组/对象的遍历、去重函数,就会触发类型报错。
正确实现命令
通过group_by按ARN对监听器数组分组,分组后每个分组仅取第一个元素的ARN打印一次,再遍历分组内所有元素打印对应协议/端口即可。
- 仅输出ARN+所有关联协议,匹配需求预期输出:
jq -r '.Listeners | group_by(.LoadBalancerArn)[] | first.LoadBalancerArn, (.[] | .Protocol)'
执行后输出(-r为原始输出模式,自动去掉JSON字符串的包裹引号,如需保留引号去掉该参数即可):
arn:aws:elasticloadbalancing:us-xxxx-1:123456789:loadbalancer/app/msword-123456789/20b73abcde HTTP HTTP HTTPS
- 如需同时输出对应端口,调整为如下命令即可:
jq -r '.Listeners | group_by(.LoadBalancerArn)[] | first.LoadBalancerArn, (.[] | "Port: \(.Port), Protocol: \(.Protocol)")'
该写法兼容多负载均衡场景,存在多个不同ARN时会自动分组,每个ARN仅打印一次,下方跟随对应所有监听器的配置信息,无需额外去重逻辑。
内容的提问来源于stack exchange,提问作者eramm
相关产品推荐
相关产品推荐

