Search code examples
shellmathversionposixstring-math

How to convert a semantic version shell variable to a shifted integer?


Given a shell variable whose value is a semantic version, how can I create another shell variable whose value is (tuple 1 × 1000000) + (tuple 2 × 1000) + (tuple 3) ?

E.g.

$ FOO=1.2.3
$ BAR=#shell magic that, given ${FOO} returns `1002003`
# Shell-native string-manipulation? sed? ...?

I'm unclear about how POSIX-compliance vs. shell-specific syntax comes into play here, but I think a solution not bash-specific is preferred.


Update: To clarify: this isn't as straightforward as replacing "." with zero(es), which was my initial thought.

E.g. The desired output for 1.12.30 is 1012030, not 100120030, which is what a .-replacement approach might provide.


Bonus if the answer can be a one-liner variable-assignment.


Solution

  • A perl one-liner:

    echo $FOO | perl -pne 's/\.(\d+)/sprintf "%03d", $1/eg'
    

    How it works:

    • perl -pne does a REPL with the supplied program
    • The program contains a replacement function s///
      • The search string is the regex \.(\d+) which matches a string beginning with dot and ends with digits and capture those digits
      • The e modifier of the s/// function evaluates the right-hand side of the s/// replacement as an expression. Since we captured the digits, they'll be converted into int and formatted into leading zeros with sprintf
      • The g modifier replaces all instances of the regex in the input string

    Demo