在Bash中将变量输出到CSV文件的帐户

时间:2018-11-29 20:42:59

标签: bash amazon-web-services csv aws-cli

我正在获取有关我们环境中的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”变量的可变性并使列正确排列?即使所有者标签不存在?

1 个答案:

答案 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