Hi,
I'm looking to transform list of objects like this below into an array of elements, so I can count them with '| length'
Want to get something like this:
[
{object1},
{object2}
]
out of this:
{
"Sid": "somesid",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxx:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::somebucket/*"
}
{
"Sid": "anothersid",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::xxxxxxxxx:root"
},
"Action": "s3:Delete*",
"Resource": [
"arn:aws:s3:::some_bucket2/*",
"arn:aws:s3:::some_bucket2"
]
}
If the entire input file fits in memory, the simple solution is jq -s length. The -s flag puts everything in the input stream into one array before passing it to your program.
If the input file is really big, use reduce to avoid reading everything into memory at once. This requires jq 1.5.
jq -n 'reduce inputs as $obj (0; .+1)'
Thank you, both suggestion do what I needed.
something | jq -s length
something | jq -n 'reduce inputs as $obj (0; .+1)'
Is it possible to do this transformation inside the same jq run?
Something like this, but without second pipe to jq:
cat bucket.json | jq -r '.Statement[] | select(.Effect!="Deny") ' | jq -n 'reduce inputs as $obj (0; .+1)'
2
Yes! Both ways can be done inside the previous jq run.
jq '[.Statement[] | select(.Effect != "Deny")] | length'
jq 'reduce (.Statement[] | select(.Effect != "Deny")) as $obj (0; .+1)'
In your particular example, there is a third way which in my opinion is the clearest:
jq '.Statement | map(select(.Effect != "Deny")) | length'
This is basically equivalent to the non-reduce way above. The map means "do this to everything inside the input array," in this case filtering out Deny effects.
Perfecto!
Thank you very much for examples.
Most helpful comment
If the entire input file fits in memory, the simple solution is
jq -s length. The-sflag puts everything in the input stream into one array before passing it to your program.If the input file is really big, use
reduceto avoid reading everything into memory at once. This requires jq 1.5.