1

I want to find the go[^ ]+ inside these two strings using expr. The output should be 1.17.6 and 1.18-becaeea119.

go version go1.17.6 linux/amd64
go version devel go1.18-becaeea119 Tue Dec 14 17:43:51 2021 +0000 linux/amd64

However, the devel part is optional and I can't figure out a way to properly ignore it with expr.

expr "$(go version)" : ".*go version go\([^ ]*\) .*"
expr "$(go version)" : ".*go version devel go\([^ ]*\) .*"

Using normal regexes, I would just (?: devel)? it, but expr doesn't support ? for some reason.

Is there any way to achieve this using expr in one command?

Nato Boram
  • 4,083
  • 6
  • 28
  • 58
  • Did you try `.*go version\( devel\)\? go\([^ ]*\) .*` and take the match from group 2? – The fourth bird Jan 13 '22 at 16:56
  • 1
    Looking at some third-party docs online, it seems like it's not possible to obtain `\2`. *If the pattern contains at least one regular expression subexpression, the string corresponding to `\1` shall be returned*. https://pubs.opengroup.org/onlinepubs/009695399/utilities/expr.html#tag_04_50_13_01 – Nato Boram Jan 13 '22 at 17:12
  • It looks impossible then – Wiktor Stribiżew Jan 13 '22 at 17:44
  • 1
    Since you want to return the go.. part and the only way is that it returns the first group, you'll have to loosen it up after _version_. Could be its the only way. `.*go version.* go\([^ ]*\) .*` – sln Jan 13 '22 at 18:17
  • See https://www.gnu.org/software/coreutils/manual/html_node/String-expressions.html – sln Jan 13 '22 at 18:25

2 Answers2

0

is that what you wanted?

.*go version [a-w ]*go\([^ ]*\) .*
arutar
  • 1,015
  • 3
  • 9
0

Use

.*go version.* go\([^[:space:]]*\) .*

EXPLANATION

--------------------------------------------------------------------------------
  .*                       any character (0 or more times)
--------------------------------------------------------------------------------
  go version               'go version'
--------------------------------------------------------------------------------
  .*                       any character (0 or more times)
--------------------------------------------------------------------------------
   go                      ' go'
--------------------------------------------------------------------------------
  \(                       group and capture to \1:
--------------------------------------------------------------------------------
    [^[:space:]]*            any character except: whitespace
                             characters (0 or more times)
--------------------------------------------------------------------------------
  \)                       end of \1
--------------------------------------------------------------------------------
                           ' '
--------------------------------------------------------------------------------
  .*                       any character (0 or more times)
Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37