Iterate through dictionaries jq - shell
The problem with your code is that an array initialization in bash looks like this:
declare -a arr=(item1 item2 item3)
Items are separated by space or newline. You can also use:
declare -a arr(
item1
item2
item3
)
However, the jq
output in the example contains both spaces and newlines, that's why the reported behaviour is as expected.
Workaround:
I would get the keys first, pipe them to a read loop and then call jq
for each item of the list:
jq -r '.images|keys[]' Contents.json | while read key ; do
echo "image --$(jq ".images[$key]" Contents.json)"
done
You can also use this jq
command if you don't care about pretty printing:
jq -r '.images[]|"image --" + tostring' Contents.json
To access a certain property of the subarray you can use:
jq -r '.images|keys[]' Contents.json | while read key ; do
echo "image --$(jq ".images[$key].filename" Contents.json)"
done
The above node will print the filename property for each node for example.
However this can be expressed much simpler using jq
only:
jq -r '.images[]|"image --" + .filename' Contents.json
Or even simpler:
jq '"image --\(.images[].filename)"' Contents.json
Comments
-
Johnykutty almost 2 years
I have a JSON like this
{ "images" : [ { "size" : "29x29", "idiom" : "iphone", "filename" : "[email protected]", "scale" : "2x" } ...... ...... { "size" : "60x60", "idiom" : "iphone", "filename" : "[email protected]", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } }
I want to iterate through each dictionary in
images
array. For that I wrotedeclare -a images=($(cat Contents.json | jq ".images[]")) for image in "${images[@]}" do echo "image --$image" done
I am expecting output that each dictionary is printing in an iteration. That is
image --{ "size" : "29x29", "idiom" : "iphone", "filename" : "[email protected]", "scale" : "2x" } image --{ "size" : "29x29", "idiom" : "iphone", "filename" : "[email protected]", "scale" : "3x" } image --{ "size" : "40x40", "idiom" : "iphone", "filename" : "[email protected]", "scale" : "2x" }
Etc
But its iterating through each and every single elements in each dictionary like
image --{ image --"size": image --"29x29", image --"idiom": image --"iphone", image --"filename": .... .... ....
What is wrong with my code
-
Johnykutty over 8 yearsThe code is working perfectly image -- is used just for distinguishing new lines wile printing
-
Johnykutty over 8 yearsOne more doubt, how can I separate each keys from the imageDict
-
Johnykutty over 8 yearsI tried jq -r '.images|keys[]' $contentsPath | while read key ; do imageDict=$(jq ".images[$key]" $contentsPath) echo "image --$imageDict" echo "filename --"$("$imageDict" | jq ".filename" ) done but its not working @hek2ml
-
Johnykutty over 8 yearsinstead of printing whole elements how can I print specific value for key sy filename in the loop
-
Johnykutty over 8 years+1 Working as expected :) a small side question. if we use like this(the while read method), is it reading from file each time or reading only once?
-
Johnykutty over 8 yearseach time in the sense in each iteration
-
hek2mgl over 8 yearsEach time. That's the drawback. I would use the
jq
-only solution I've suggested. -
Johnykutty over 8 yearsLet us continue this discussion in chat.
-
Johnykutty over 8 yearsI also like reading only one, but my need is to read 2-3keys from the dictionary and process them. Anywyay this is working fine