我正在获取有关我们环境中的AWS实例的一些信息,并将其转储到CSV文件中。
问题是有些行带有一个名为“ owner”的标签,有些则没有。
对于带有owner标签的行,输出看起来正确并与列标题对齐:
Host Name Instance ID Private IP Launch Time Instance State Owner AWS Account Name Account Number
USAMZAPD1026 i-593c4fb4 10.1.232.26 2014-10-08T14:44:50.000Z stopped llindsay company-lab 123456789101
但是,如果所有者标签不存在,则帐户名和帐号将出现在错误的列中:
Host Name Instance ID Private IP Launch Time Instance State Owner AWS Account Name Account Number
USMDCP1028-AWS i-86533615 10.1.233.18 2016-11-03T15:01:52.000Z stopped company-lab 123456789101
这是我用来收集信息并将其转储到文件中的代码:
echo "Host Name,Instance ID,Private IP,Launch Time, Instance State, Owner, AWS Account Name, Account Number" >> "$ofile"
readarray -t aws_instance_list < <(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [(.Tags[]|select(.Key=="Name")|.Value), .InstanceId, .PrivateIpAddress, .LaunchTime, .State.Name, (.Tags[]|select(.Key=="Owner")|.Value)] | @csv' | sed 's/"//g')
for ((instance_index=0;instance_index<${#aws_instance_list[@]};++instance_index)); do
instance_info="${aws_instance_list[$instance_index]}"
echo "$instance_info"
echo "$instance_info,$aws_account,$aws_account_number" >> "$ofile"
done # Instance Loop
done # Account Loop
以下是该aws命令的输出示例,其中包括变量输出。有些行列出了所有者,有些则没有。
USAMZDBD1165,i-eb836cc6,10.1.232.165,2016-02-17T17:39:24.000Z,stopped,llindsay
USAMZAPD2058,i-3f5721d2,10.1.233.58,2017-04-03T18:10:37.000Z,running,nalkema
USAMZAPD2056,i-3e5721d3,10.1.233.56,2016-06-21T18:50:19.000Z,running,nalkema
USAMZAPD2057,i-315721dc,10.1.233.57,2015-05-28T20:02:55.000Z,running,nalkema
USAMZAPD1027,i-685cfd87,10.1.232.27,2015-02-11T20:22:08.000Z,stopped,llindsay
core-usawsnproddfw,i-2cedae9f,10.48.136.36,2017-03-17T15:37:52.000Z,running
UAWSCDAP0001,i-5e31c15f,10.48.131.176,2018-10-23T17:23:21.000Z,running,Eric Somebody
USMDPB1027-AWS,i-0be1611d,10.48.128.37,2016-11-11T16:08:14.000Z,stopped
usamzdbd2153,i-7e0d8b91,10.1.233.153,2015-02-19T16:57:57.000Z,running,tsenti
如何考虑“ $ instance_info”变量的可变性并使列正确排列?即使所有者标签不存在?
答案 0 :(得分:1)
没有任何输入或输出可使用。只需使用上面的示例,您就可以打印到文件,然后只需计算列数即可确定标题是什么:
尝试计数列:
readarray -t aws_instance_list < <(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [(.Tags[]|select(.Key=="Name")|.Value), .InstanceId, .PrivateIpAddress, .LaunchTime, .State.Name, (.Tags[]|select(.Key=="Owner")|.Value)] | @csv' | sed 's/"//g')
for ((instance_index=0;instance_index<${#aws_instance_list[@]};++instance_index)); do
instance_info="${aws_instance_list[$instance_index]}"
echo "$instance_info"
echo "$instance_info,$aws_account,$aws_account_number" > values.txt
numlines=$(awk '-F "," {print NF}' values.txt)
if [[ "$numlines" -eq 8 ]]; then
echo "Host Name,Instance ID,Private IP,Launch Time, Instance State, Owner, AWS Account Name, Account Number" >> "$ofile"
else
echo "Host Name,Instance ID,Private IP,Launch Time, Instance State, AWS Account Name, Account Number" >> "$ofile"
fi
done # Instance Loop
done
现在我们有更多信息,我将尝试另一种方法: 您可以提出以下要求吗?
readarray -t aws_instance_list < <(aws ec2 describe-instances | jq -r ' (.Tags[]|select(.Key=="Owner")|.Value)] | @csv' | sed 's/"//g' | sort -u)
这样,您将只抓住所有者并按唯一值排序。 尝试将其放置在文件中,您可以在其中将其放置在数组中(或直接将其放置在数组中):
IFS=$'\r\n' GLOBIGNORE='*' command eval 'owners=($(<filename))'
在这一点上,执行您生成的文件,其中文件的值不包含标题。
readarray -t aws_instance_list < <(aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [(.Tags[]|select(.Key=="Name")|.Value), .InstanceId, .PrivateIpAddress, .LaunchTime, .State.Name, (.Tags[]|select(.Key=="Owner")|.Value)] | @csv' | sed 's/"//g')
for ((instance_index=0;instance_index<${#aws_instance_list[@]};++instance_index)); do
instance_info="${aws_instance_list[$instance_index]}"
echo "$instance_info"
echo "$instance_info,$aws_account,$aws_account_number" >> values.txt
done # Instance Loop
done # Account Loop
定义两个标头,一个标有Owner,另一个标不带:
echo "Host Name,Instance ID,Private IP,Launch Time, Instance State, Owner, AWS Account Name, Account Number" >> "$ownerfile"
echo "Host Name,Instance ID,Private IP,Launch Time, Instance State, AWS Account Name, Account Number" >> "$nofile"
完成此操作后,您可以采用两种方法:
环顾所有人群:
for (( a = 0; a < ${#owners[@]}; a++ )); do
grep -w ${owners[a]} values.txt >> "$ownerfile"
grep -v ${owners[a]} values.txt >> "$nofile"
done
获取列所有者的值,并在您自己的循环中检查值是否存在于所有者数组中,如下所示:
if [[ " ${owners[@]} " =~ " ${value} " ]]; then
echo "$instance_info,$aws_account,$aws_account_number" >> "$ownerfile"
fi
if [[ ! " ${owners[@]} " =~ " ${value} " ]]; then
echo "$instance_info,$aws_account,$aws_account_number" >> "$nofile"
fi
更精通awk的人可以通过直接检查列的值并打印必要的内容来帮助您进一步减少费用,但这超出了我的范围。
这里是一个如何完成列值检查的示例(如果您知道如何从此处继续进行或其他人这样做):
awk '$7 = "owner" {print $0}'
BR