1

I am trying to extract the version information a string using sed as follows

echo "A10.1.1-Vers8" | sed -n "s/^A\([0-9]+\)\.\([0-9]\)\.[0-9]+-.*/\1/p"

I want to extract '10' after 'A'. But the above expression doesn't give the expected information. Could some one please give some explanation on why this statement doesn't work ?

I tried the above command and changed options os sed but nothing works. I think this is some syntax error

echo "A10.1.1-Vers10" | sed -n "s/^X\([0-9]+\)\.\([0-9]\)\.[0-9]+-.*/\1/p"

Expected result is '10' Actually result is None

user2677279
  • 127
  • 3
  • 10

2 Answers2

2
$ echo "A10.1.1-Vers8" | sed -r 's/^A([[:digit:]]+)\.(.*)$/\1/g'
10

Search for string starting with A (^A), followed by multiple digits (I am using POSIX character class [[:digit:]]+) which is captured in a group (), followed by a literal dot \., followed by everything else (.*)$.

Finally, replace the whole thing with the Captured Group content \1.

In GNU sed, -r adds some syntactic sugar, in the man page, it is called as --regexp-extended

slayedbylucifer
  • 22,878
  • 16
  • 94
  • 123
1

GNU grep is an alternative to sed:

$ echo "A10.1.1-Vers10" | grep -oP '(?<=^A)[0-9]+'
10

The -o option tells grep to print only the matched characters.

The -P option tells grep to match Perl regular expressions, which enables the (?<= lookbehind zero-length assertion.

The lookbehind assertion (?<=^A) ensures there is an A at the beginning of the line, but doesn't include it as part of the match for output.

If you need to match more of the version string, you can use a lookforward assertion:

$ echo "A10.1.1-Vers10" | grep -oP '(?<=^A)[0-9]+(?=\.[0-9]+\.[0-9]+-.*)'
10
Jon
  • 3,573
  • 2
  • 17
  • 24