TPens
TPens

Reputation: 59

Regular expression to extract version number

I want to extract the version number from the ld -v command and I have written the following sed expression:

ld -v | sed -r 's/.+([0-9|\.]+)/\1/'

However this outputs 1, which is the last digit of the version number. The result I expect is 2.35.1

Where did I go wrong with my regular expression? How I understand it the .+ part matches all characters and whitespace and ([0-9|\.]+) matches a digit or a dot and then captures this. \1 then references the captured bit.

Upvotes: 4

Views: 858

Answers (4)

costaparas
costaparas

Reputation: 5237

Use grep instead, with the -o option to extract just the matched component:

ld -v | grep -Eo '[0-9]+(\.[0-9]+)*$'

Note this also anchors the match to the end of the line.

The pattern itself allows for any amount of . in it. Generally, version numbers have a MAJOR, MINOR and PATCH -- so at most 2 ., but it doesn't hurt to match more in this case.

You could be more specific, and only match up to two .:

ld -v | grep -Eo '[0-9]+(\.[0-9]+){0,2}$'

Note: in both cases, we allow for situations where the version number may omit the MINOR and/or PATCH -- e.g. version 2.35 rather than 2.35.1

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133770

With awk could you please try following, written and tested in GNU awk.

ld -v | 
awk 'match($0,/([0-9]+\.){1,}[0-9]+$/){print substr($0,RSTART,RLENGTH)}'

Explanation: Adding detailed explanation for above.

ld -v |                                ##Running ld -v command and sending output to awk program from here.
awk '                                  ##Starting awk program from here.
match($0,/([0-9]+\.){1,}[0-9]+$/){     ##using match function to match digits followed by dot with 1 ore more occurrences and then digits till last of line.
  print substr($0,RSTART,RLENGTH)      ##Printing sub string of matched regex which prints from RSTART to till RLENGTH values.
}'

Upvotes: 2

Timur Shtatland
Timur Shtatland

Reputation: 12465

Use GNU grep like so:

ld -v | grep -Po '[\d.]+' | head -n1

Output:

2.25.1

Here, grep uses the following options:
-P : Use Perl regexes.
-o : Print the matches only (1 match per line), not the entire lines.

[\d.]+ : Any digit or a literal dot, repeated 1 or more times.

SEE ALSO:
grep manual
perlre - Perl regular expressions

Upvotes: 3

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627537

You can use

ld -v | sed -rn 's/.+ ([0-9.]+).*/\1/p'

Details

  • -r (or -E) - enables POSIX ERE expression syntax

  • -n - suppresses default line output

  • .+ ([0-9.]+).* - matches any one or more chars, a space, and then captures one or more digits and . into Group 1, and then any zero or more chars

  • \1 - replaces the match with Group 1 contents

  • p - prints the result of the substitution.

Upvotes: 1

Related Questions