Using jq with bash to run a command for each object in an array

How can I run a bash command for every json object in a json array using jq? So far I have this:

cat credentials.json | jq -r '.[] | .user, .date, .email' | mycommand -u {user} -d {date} -e {email} 

This does not work. How can I take parameters from json array to my command?

My json file looks something like this:

 [ "user": "danielrvt", "date": "11/10/1988", "email": " myemail@domain.com ", ... ] 
+15
source share
5 answers

It is best to output each entry in TSV format and then read this from the shell loop.

 jq -r '.[]|[.user, .date, .email] | @tsv' | while IFS=$'\t' read -r user date email; do mycommand -u "$user" -d "$date" -e "$email" done 

jq itself has nothing like calling system to run an external command from a filter, although it seems that they work on it .

+20
source

You could jq output commands to execute, something like

 .[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)" 

Then do it. Sort of

 bash <(jq -r '.[] | "mycommand \(.user|@sh) \(.date|@sh) \(.email|@sh)"' foo) 
+9
source

With xargs:

 curl localhost:8082/connectors | jq .[] | xargs -L1 -I'{}' curl -XDELETE 'localhost:8082/connectors/{}' 

Or equivalently, to show the output of this first curl:

 echo '["quickstart-file-sink4","quickstart-file-source","quickstart-file-sink","quickstart-file-sink2","quickstart-file-sink3","quickstart-file-source2"]' | jq .[] | xargs -L1 -I'{}' curl -XDELETE 'localhost:8082/connectors/{}' 

jq .[] removes one level of content so that the list becomes output as one line per element.

xargs -L1 processes one line at a time

xargs -I'{}' indicates that the line {} should be replaced by the input line when the next command is called.

xargs is essentially a mapping operator for the shell.

+6
source

I recently ran into the same issue when xargs doesn't help much because of the relatively complex set of arguments I would like to pass. Thus, I implemented a filter sh (and his friends) for jq. I still did not have enough time to write documentation and tests for it, so I did not create a PR so that it became part of the official code base. So now it is only for those who are ready to independently compile this version:

https://github.com/haochenx/jq/tree/sh-support

+2
source

Here is another option that I based on @chepner's answer.

 echo "$config" | jq -c '.[]' | while IFS=$"\n" read -rc; do echo "start" host=$(echo "$c" | jq -r '.host') echo $host echo "end" done 

I used the jq -c option to output "compact" jsons so that they are all on the same line.

In combination with IFS=$"\n" I was able to loop through each element in the json input array and do what I wanted.

So, with the input

 [ { "host": "host1", "settings": {} }, { "host": "host1", "settings": {} } ] 

output

 start host1 end start host2 end 
0
source

Source: https://habr.com/ru/post/1266272/


All Articles