0

I am looking for a regular expression in my jq query (using. It's a pretty simple one, I want to match entries starting with a number \d (or [0-9]) and ending in linux. What I've tried so far:

versions=`echo $allversions| jq '.tags[] | select(startswith("\d")) | select(endswith("linux"))'`

but I don't think startwith doesn't support regular expression. I'm reading that match supports regular expression, but I cannot find proper documentation or examples about it. A simple 'jq '.tags[]| match("\d.*linux")' doesn't work and gives a syntax error message:

syntax error near unexpected token `"\d*linux"'

How can I accomplish this? Or should I combine jq with sed instead?

FYI:

$ jq --version
jq-1.6
Casper Dijkstra
  • 1,615
  • 10
  • 37
  • 1
    BTW, `echo $allversions` is itself buggy. See [I just assigned a variable, but `echo $variable` prints something else](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else). Always, _always_ quote your expansions: `echo "$allversions"` -- see what happens if your JSON contains a string with a `*` surrounded by whitespace (and you're using a POSIX-compliant shell, notably _not_ zsh) otherwise. – Charles Duffy Apr 05 '21 at 16:50
  • ...that is to say, `json='{"key": "this is * a string"}'; echo $json` can have a list of files in the current directory injected into your string. (Not the only way unquoted expansions can corrupt a string, but one of the more dramatic ones). – Charles Duffy Apr 05 '21 at 16:52

2 Answers2

2

Ok I found how to do it!

jq -r '.tags[] | select(test("^[0-9].*linux"))'
Casper Dijkstra
  • 1,615
  • 10
  • 37
  • 1
    You want a `$` on the end to be equivalent to `endswith`. Right now this will succeed if `linux` is anywhere in the string. – Charles Duffy Apr 05 '21 at 16:51
2

The arguments to regex functions must be JSON strings, so any regex backslash must be escaped. Thus, instead of match("\d.*linux") you'd write:

match("\\d.*linux")

peak
  • 105,803
  • 17
  • 152
  • 177