0

给定一个值为语义版本的 shell 变量,如何创建另一个值为(tuple 1 × 1000000) + (tuple 2 × 1000) + (tuple 3)的 shell 变量?

例如

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

我不清楚 POSIX 合规性与特定于 shell 的语法如何在这里发挥作用,但我认为首选不是特定于 bash 的解决方案。


更新:澄清一下:这并不像.用零替换“”那么简单,这是我最初的想法。

例如,期望的输出1.12.30is 1012030, not 100120030,这是.-replacement 方法可能提供的。


如果答案可以是单行变量赋值,则奖励。

4

4 回答 4

2

perl 单行:

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

这个怎么运作:

  • perl -pne使用提供的程序执行REPL
  • 该程序包含替换功能s///
    • 搜索字符串是\.(\d+)匹配以点开头并以数字结尾的字符串并捕获这些数字的正则表达式
    • 函数e修饰符s///将替换的右侧计算s///为表达式。由于我们捕获了数字,它们将被转换为 int 并使用sprintf格式化为前导零
    • g修饰符替换输入字符串中正则表达式的所有实例

演示

于 2021-04-30T00:13:59.527 回答
1

在点上拆分,然后循环并乘/加:

version="1.12.30"

# Split on dots instead of spaces from now on
IFS="."

# Loop over each number and accumulate
int=0
for n in $version
do
  int=$((int*1000 + n))
done

echo "$version is $int"

请注意,这将 1.2 和 0.1.2 视为相同。如果您想始终将第一个数字视为主要/百万,请事先考虑填充/截断。

于 2021-04-29T23:53:54.407 回答
0

这个怎么样?

$ ver=1.12.30
$ foo=$(bar=($(echo $ver|sed  's/\./ /g')); expr ${bar[0]} \* 1000000 + ${bar[1]} \* 1000 + ${bar[2]})
$ echo $foo
1012030
于 2021-04-30T00:07:43.400 回答
0

这应该这样做

echo $foo | sed 's/\./00/g'
于 2021-04-29T23:31:57.440 回答