1

I am searching through Azure container and want to filter out blobs ending with certain suffixes. When I use the --query parameter with a JMESPath contains function, it is giving me an error.

When I run the command

az storage blob list \
    --account-name $account_name \
    --account-key $key \
    --num-results $numResults \
    --show-next-marker \
    --container-name $container_name \
    --query [].name

it runs without any error.

When I change the query to

    --query [].name[?contains(@,'R00005006')=='true']

or

    --query [].name[?contains(@,'R00005006')]

I get this error:

syntax error near unexpected token `('

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83

2 Answers2

0

You need to put the query in quotes for it to be parsed correctly by the command prompt as well as create a projection for it be properly parsed.

az storage blob list \
    --account-name $account_name \
    --account-key $key \
    --num-results $numResults \
    --show-next-marker \
    --container-name $container_name \
    --query "[*].name | [?contains(@, 'R00005006') == `true`]"

Take note that true is surrounded with a backtick.

tj-cappelletti
  • 1,774
  • 12
  • 19
0

If you are looking for the whole blob object content, then you should have your condition on the array of blob objects:

[?contains(name, `R00005006`)]

So, in you Azure command:

az storage blob list \
  --account-name $account_name \
  --account-key $key \
  --num-results $numResults \
  --show-next-marker \
  --container-name $container_name \
  --query '[?contains(name, `R00005006`)]'

If you are just looking for a list of names indeed, you have to stop the list projection created by .name with a pipe expression:

[].name | [?contains(@, `R00005006`)]

So, in your Azure command:

az storage blob list \
  --account-name $account_name \
  --account-key $key \
  --num-results $numResults \
  --show-next-marker \
  --container-name $container_name \
  --query '[].name | [?contains(@, `R00005006`)]'
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • Thanks a lot. This worked for me.. --query "[].name | [?contains(@, '12878')]" continuation questions, 1. how can I search for multiple matching patterns? like, 12878*vcf.gz or 12878*hard-filtered.vcf.gz and so on. 2. Is there a way to do for loop if I have a whole list of numbers to match for those patterns, or I should simply write a bash script and run this code multiple times. TIA – Priyank Shukla Mar 09 '23 at 21:51
  • You can definitely have a or `||` and/or an and `&&`, or a mix of both in that filter, e.g.: `[].name | [?(contains(@, '123') && contains(@, 'vcf.gz')) || (contains(@, '345') && contains(@, 'hard-filtered.vcf.gz'))]`. – β.εηοιτ.βε Mar 09 '23 at 22:12
  • As for the for loop, no, you could probably do a more complex contains that fits your need but that would defiantly need more input from your side (i.e.: an example JSON output of that Azure command and a desired output). – β.εηοιτ.βε Mar 09 '23 at 22:15
  • awesome.. That helped a lot. another leading question: Is there a way that I can query for substring ending with a pattern or not matching the pattern? – Priyank Shukla Mar 10 '23 at 14:47
  • Apart from `contains`, you also have a [`starts_with`](https://jmespath.org/specification.html#starts-with) and a [`ends_with`](https://jmespath.org/specification.html#ends-with) functions that you can use the same way, yes. – β.εηοιτ.βε Mar 10 '23 at 17:03