Sometimes you are just too busy to get the work done and don’t have time to understand why things work like they do. Aws -cli option --output=text was one those details I never really took time to understood. Sometimes I got my output formated one item per line, sometimes all items were on single line with no apparent reason.

For example listing EC2 instance IDs like this will print them all on single line

$ aws ec2 describe-instances --output text \
--query 'Reservations[].Instances[].InstanceId'
i-0a7f2e35af95cfb99	i-09a0eb1122fa5f837	i-03e0da94ae68abee1 ...

But if you list IDs with instance types, output will be one instance per line

$ aws ec2 describe-instances --output text \
--query 'Reservations[].Instances[].[InstanceId, InstanceType]'
i-0a7f2e35af95cfb99 m5.large
i-09a0eb1122fa5f837 t2.medium
i-03e0da94ae68abee1 c3.large
...

But there is logical reason for this. It will be obvious when you look at JSON output of commands.

[
    "i-0a7f2e35af95cfb99", 
    "i-09a0eb1122fa5f837", 
    "i-03e0da94ae68abee1", 
...
]

vs.

[
	[
		"i-0a7f2e35af95cfb99",
		"m5.large"
	],
	[
		"i-09a0eb1122fa5f837",
		"t2.medium"
	],
	[
		"i-03e0da94ae68abee1",
		"c3.large"
	],
...
]

--output=text will print everything within innermost [] brackets on single line. The First JSON output was flat so there was no line-breaks between items. Second has 2-level structure so every InstanceId & InstanceType -pair is separated by newline.

Adding brackets around InstanceId in query will then split output into multiple lines.

$ aws ec2 describe-instances --output text \
--query 'Reservations[].Instances[].[InstanceId]'
i-0a7f2e35af95cfb99
i-09a0eb1122fa5f837
i-03e0da94ae68abee1
...

Mystery solved!