起初我认为上面的join() 解决方案不起作用。然后我意识到我正在“过度喂养”join() 过滤器,导致它失败,因为我提供的不仅仅是一个简单的数组作为输入。我已将多个过滤器与, 连接起来,但未能限制join() 的范围。
没用:
jq -r \
'.ansible_facts |
.ansible_hostname,
.ansible_all_ipv4_addresses | join(" "),
.ansible_local."aws-public-ipv4".publicIP'
这给出了错误,
jq: error (at <stdin>:0): Cannot iterate over string ("hostone")
因为 jq 不仅试图“消费”ansible_all_ipv4_addresses,而且还试图“消费”前面的 ansible_hostname 过滤器的输出(我不确定这是为什么,或者它是否是 jq 的作者有意为之)。
有效:
jq -r \
'.ansible_facts |
.ansible_hostname,
(.ansible_all_ipv4_addresses | join(" ")),
.ansible_local."aws-public-ipv4".publicIP'
在这里,我将join() 限制为仅.ansible_all_ipv4_addresses(ansible_all_ipv4_addresses 是我希望转换为单个空格分隔的字符串的 IP 地址数组)。
P.S.:我发现@sh 过滤器会根据需要生成以空格分隔的输出,但另外用单引号分隔每个输出项。
附言:
这是我的解决方法,直到我发现join() 的工作原理与正确使用时相同(见上文):
jq -r '.Accounts[].Id | @tsv | sub("\t";" ";"g")'
解释:@tsv 过滤器产生 Tab S分隔的 V 值,然后是 @987654337 @filter 用空格替换制表符,globally。