0

I have a number of ec2 instances running in AWS, and I've extracted this information into a file.

aws ec2 describe-instances > instances.json

I also have another file ipAddressList

cat ipAddressList

10.100.39.4
10.100.56.20
10.100.78.11
10.100.78.12

I would like to extract the ImageId for these 4 instances.

I'm able to get the ImageId for individual ip addresses using this command

cat instances.json | jq '.Reservations[] | .Instances[] | select(.PrivateIpAddress == "10.100.39.41") | .ImageId'

But I would like to put this into a bash loop to extract the ImageId's for all 4 instances at once.

I've tried

for i in `cat ipAddressList` ; do jq '.Reservations[] | .Instances[] | select(.PrivateIpAddress == \$i) | .ImageId' instances.json ; done

But it throws an error. What am I doing wrong please?

Metro
  • 873
  • 8
  • 19
  • Does https://stackoverflow.com/questions/34745451/passing-arguments-to-jq-filter answer your question? – KamilCuk Aug 04 '22 at 09:44
  • _But it throws an error._ : Is it asked to much to also write error message in your question, i.e. do you expect everyone to guess the error message? – user1934428 Aug 04 '22 at 10:21

2 Answers2

4

Don't inject data into code, use the --arg and --argjson options provided by jq to do that safely:

for i in `cat ipAddressList`
  do jq --arg i "$i" '
    .Reservations[] | .Instances[]
    | select(.PrivateIpAddress == $i) | .ImageId
  ' instances.json
done

On top of that, jq provides options to read in files as raw text, so you could shift the entire loop into jq logic, resulting in just one invocation of jq:

jq --rawfile ips ipAddressList '
  .Reservations[].Instances[]
  | select(IN(.PrivateIpAddress; ($ips / "\n")[])).ImageId
' instances.json
pmf
  • 24,478
  • 2
  • 22
  • 31
3

You're really close with your solution.

What you need is

for i in `cat ipAddressList` ; do jq '.Reservations[] | .Instances[] | select(.PrivateIpAddress == "'$i'") | .ImageId' instances.json ; done

And you should be fine.

Hammed
  • 1,457
  • 1
  • 24
  • 37