Home > Mobile >  Execute shell script string array in a particular order
Execute shell script string array in a particular order

Time:07-27

I have an array of AWS Cloudformation stacks names in stackList. Now this contains all the stacks in my AWS account, I want to delete them, but in a particular order.

Lets say the stackList contains the following string array:

aaa-bbb-ccc
aaa-ccc-ddd
aaa-ggg-ddd
bbb-ccc-ddd
mmm-nnn-yyy

I have some patterns like the cloudformation stack starts with mmm* should get deleted first, the stacks ending with *ddd should be second etc.

What is the easiest and most efficient way in doing this?

EDIT

To better explain the question, I am adding the some of the code below:

stackList="$(aws cloudformation describe-stacks | jq -r '.Stacks[].StackName')"
for stack_name in ${stackList}; do
   stack_id="$(aws cloudformation describe-stacks --stack-name ${stack_name} | jq -r '.Stacks[].StackId')"
   aws cloudformation delete-stack --stack-name "${stack_id}"
   echo "Deleting cloudformation stack ${stack_name}"
   aws cloudformation wait stack-delete-complete --stack-name "${stack_id}"
done

Now I want cloudformation stacks related to infrastructure users and credentials to be deleted last, For example, below is the order in which I want it to get deleted but the describestacks can also contain other entries, as well as the order, could be different in other landscapes.

aws-persistence-infrastructure
aws-persistence-users
aws-firewall-infrastructure
aws-network-infrastructure
aws-infrastructure-users
bootstrap-credentials-aws

I can use grep as answered below but if there is any more efficient method, it would be nice.

CodePudding user response:

grep for example:

stackList='
    aaa-bbb-ccc
    aaa-ccc-ddd
    aaa-ggg-ddd
    bbb-ccc-ddd
    mmm-nnn-yyy
'

grep -E '^mmm' <<< $stackList 
grep -E 'ddd$' <<< $stackList 

mmm-nnn-yyy
aaa-ccc-ddd
aaa-ggg-ddd
bbb-ccc-ddd

CodePudding user response:

A common arrangement for producing a custom sort order is the "decorate-sort-undecorate" pattern. Here's a quick demo.

aws cloudformation describe-stacks |
jq -r '.Stacks[].StackName' |
awk '{ key=1 }
   /-infrastructure-users$/ { key  = 10 }
   /-credentials-/ { key  = 100 }
   { print key "\t" $0 }' |
sort -n |
# for debugging
tee /dev/stderr |
cut -f2 - |
while read -r stack_name; do
    :

The pipe to tee /dev/stderr is just for debugging, so you can examine the output from sort. I obviously had to guess a bit as to what your precise requirements are. Here's a brief demo with just the Awk and sort applied to your example data: https://ideone.com/5775Ts

1   aws-firewall-infrastructure
1   aws-network-infrastructure
1   aws-persistence-infrastructure
1   aws-persistence-users
11  aws-infrastructure-users
101 bootstrap-credentials-aws

With cut -f2- we discard the number field we added for sort (that's the "undecorate" part).

If you had stacks which matched both -infrastructure-users and -credentials- they would get a sort key of 111 and end up after all the others; if that's not what you want, you can probably figure out how to change the weights. For example, if you want to put -persistence- earlier in the list, you could subtract one if you saw that pattern in the Awk script.

Tangentially, nothing here except /dev/stderr is Bash-specific. If you wanted to use arrays, those are Bash only, but uses a different syntax. Perhaps see also Difference between sh and bash.

Also, as a stylistic remark, probably don't use variables just to capture the things you then immediately loop over. The above code replaces your for loop with a while read -r loop; perhaps see also https://mywiki.wooledge.org/DontReadLinesWithFor

  • Related