问题
I have a JSON like this
{
"images" : [
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
}
......
......
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
I want to iterate through each dictionary in images
array.
For that I wrote
declare -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" : "Icon-Small@2x.png",
"scale" : "2x"
}
image --{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@3x.png",
"scale" : "3x"
}
image --{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Spotlight-40@2x.png",
"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
回答1:
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
来源:https://stackoverflow.com/questions/34529156/iterate-through-dictionaries-jq-shell