删除字符串的第二个点并在字符之间添加 0

删除字符串的第二个点并在字符之间添加 0

我在变量 (XYZ) 中有语义版本控制字符串。我需要改变这一点,以便第二个点消失,如果 Z 只有一位数字,则我将 Y 和 Z 连接起来,并用 0 分隔,如果 Z 有两位数字,则直接连接。

所以基本上是这样的:

1.5.0 -> 1.500
1.5.1 -> 1.501
1.4.7 -> 1.407
1.4.10 -> 1.410
1.4.24 -> 1.424

我怎样才能使用 bash 做到这一点?

答案1

在任何 POSIX shell 中,包括bash, 使用${var##pattern}${var%pattern}ksh 运算符:

case $string in
  (*.*.*)
     minor=${string##*.}
     case $minor in
       (? | "") minor=0$minor
     esac
     string=${string%.*}$minor
esac

特别是对于 bash-3.2+(并且未启用 bash 3.1 兼容性),您还可以执行以下操作:

if [[ $string =~ ^(.*\..*)\.([^.]*)([^.])$ ]]; then
  string=${BASH_REMATCH[1]}${BASH_REMATCH[2]:-0}${BASH_REMATCH[3]}
fi

答案2

使用参数扩展。

#!/bin/bash

declare -A expect=(
    [1.5.0]=1.500
    [1.5.1]=1.501
    [1.4.7]=1.407
    [1.4.10]=1.410
    [1.4.24]=1.424
)

new_version() {
    prefix=${1%%.*}
    suffix=${1##*.}
    middle=${1#*.}
    middle=${middle%.*}
    printf %s.%s%02d "$prefix" "$middle" "$suffix"

}

for old in "${!expect[@]}" ; do
    new=$(new_version $old)
    if [[ ${expect[$old]} == $new ]] ; then
        echo ok
    else
        echo not ok: in: $old expect: ${expect[$old]} got: $new
    fi
done

答案3

在 Bash 中,使用read分割和printf补零。通过变量的输入old和输出new(以使用一些临时变量为代价):

old=1.4.24
IFS=. read -r a b c  <<< "$old"
printf -v new "%s.%s%02d" "$a" "$b" "$c"
echo "$old -> $new"

那应该打印1.4.24 -> 1.424

答案4

短的awk解决方案:

测试用例:

ver_num="1.4.10"
awk -F'.' '{ printf "%d.%d%.2d", $1, $2, $3 }' <<<"$ver_num"
1.410

ver_num="1.5.0"
awk -F'.' '{ printf "%d.%d%.2d", $1, $2, $3 }' <<<"$ver_num"
1.500

ver_num="1.4.77"
awk -F'.' '{ printf "%d.%d%.2d", $1, $2, $3 }' <<<"$ver_num"
1.477

相关内容