我在尝试处理' aws ec2 describe-instances'的输出时遇到了问题。命令' jq',我真的需要一些帮助。
我想将JSON输出转换为包含所有实例列表的CSV文件 列'名称,InstanceId,Tag-Client,Tag-CostCenter'。
我一直在使用jq的选择,其命令如下:
aws ec2 describe-instances |
jq -r '.Reservations[].Instances[]
| (.Tags[]|select(.Key=="Name")|.Value) + "," + .InstanceId + ","
+ (.Tags[]|select(.Key=="Client")|.Value) + ","
+ (.Tags[]|select(.Key=="CostCenter")|.Value)'
但是,以这种方式使用选择,只显示包含所有标记的条目,而不显示仅包含其中一个标记的条目。
我理解行为,类似于grep,但是我试图弄清楚是否可以使用jq执行此操作,因此在没有定义一个标记的情况下,只会返回字符串""而不是删除整行。
我找到了关于使用' if' jq中的子句([https://ilya-sher.org/2016/05/11/most-jq-you-will-ever-need/],但在任何人都想知道已经解决了这种情况,而不必在不同的执行中制作这个逻辑或拆分命令。
答案 0 :(得分:0)
每当给定一组键/值对(此处为标记)并且您希望通过其键提取值时,将它们映射到对象中会更容易,因此您可以直接访问它们。像from_entries
这样的函数可以很好地解决这个问题。
但是,由于您还尝试检索不在此标记数组中的值,因此您可以稍微改变它以保存一些步骤。使用reduce
或foreach
,您可以浏览每个标记并将其添加到包含您感兴趣的所有值的对象中。然后您可以将所需的值映射到数组中转换为csv行。
因此,如果您的目标是为每个实例创建Tags[Name], InstaceId, Tags[Client], Tags[CostCenter]
行,则可以执行以下操作:
# for each instance
.Reservations[].Instances[]
# map each instance to an object where we can easily extract the values
| reduce .Tags[] as $t (
{ InstanceId }; # we want the InstanceId from the instance
.[$t.Key] = $t.Value # add the values to the object
)
# map the desired values to an array
| [ .Name, .InstanceId, .Client, .CostCenter ]
# convert to csv
| @csv
好消息是,如果标记数组中不存在Name
,Client
或CostCenter
,甚至InstanceId
,那么它们只是是转换为csv时变为空的null
。