Commands like the AWS CLI may return a list of values all in one line, where each item in the list is separated by the nearby items with spaces. Using a plain read
command doesn’t really work: read
will read all the values in one go into the variable. You need to change the delimiter that read
uses to split the input. No need to pipe the output through Perl or other tools, read
got you covered with the -d
option.
In this example I get the list of the ARNs of all target groups in an AWS account, and then iterate over those ARNs to list all the instances in each target group. The ouput will also be saved into a file through the tee
command:
aws elbv2 describe-target-groups \
--query 'TargetGroups[].TargetGroupArn' \
--output text | \
while read -d ' ' ARN ; do \
echo -n "$ARN: " ; \
aws elbv2 describe-target-health \
--target-group-arn "$ARN" \
--query 'TargetHealthDescriptions[].Target.Id' \
--output text ; sleep 1 ; \
done | \
tee tg-instances.txt
The ouput of this one liner will be in the format:
ARN: instance_ID [instance_ID...]
Things to notice:
- the AWS CLI’s
describe-target-groups
command will list all target groups’ ARNs thanks to the--query
option and list as many as possible on single lines, according to the shell’s output buffer capacity; the ouput is piped through awhile
loop; - the while loop uses
read -d ' '
to split each line at spaces and save each item in the$ARN
variable, one per cycle; - the
echo
command prints the value of$ARN
followed by a colon, a space, but will not output a newline sequence due to the-n
option; - the AWS CLI’s
describe-target-health
command will list all target IDs thanks to the--query
option and print them out in a single line; it will also provide a newline sequence, so that the next loop will start on a new line; - the
sleep 1
command slows down the loop, so that we don’t hammer the API to the point that they will rate limit us; - finally, the
tee
command will duplicate the output of the while loop to both the standard output and the filetg-instances.txt
.