我想知道如何使用bash来修改版本号中的最后一位数。
e.g。
VERSION=1.9.0.9
NEXT_VERSION=1.9.0.10
编辑:版本号只包含自然数。
解决方案是否可以通用,以处理版本号中的任意数量的部件。
e.g。
1.2
1.2.3
1.2.3.4
1.2.3.4.5
答案 0 :(得分:8)
让我们从迈克尔的基本答案开始:
VERSIONS="
1.2.3.4.4
1.2.3.4.5.6.7.7
1.9.9
1.9.0.9
"
for VERSION in $VERSIONS; do
echo $VERSION | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g'
done
我们如何才能改善这一点?以下是从大量评论中提取的一堆想法。
程序中的尾随“1”对其操作至关重要,但它不是最明确的做事方式。最后的奇数'1'是一个布尔值,它是真的,因此匹配每一行并触发默认操作(因为后面的括号内没有动作),这是打印$ 0,行读取,修改为上一个命令。
因此,为什么不使用awk
命令来避免sed
命令?
awk -F. '{$NF+=1; OFS="."; print $0}'
当然,我们可以在几个阶段进一步改进。你可以使用bash'<<<<字符串重定向操作符以避免管道:
awk -F. '...' <<< $VERSION
接下来的观察是,给定一系列行,只需执行一次awk即可处理它们:
echo "$VERSIONS" | awk -F. '/[0-9]+\./{$NF+=1;OFS=".";print}'
没有for循环。 “$ VERSION”周围的双引号保留字符串中的换行符。管道仍然是不必要的,导致:
awk -F. '/[0-9]+\./{$NF+=1;OFS=".";print}' <<< "$VERSIONS"
正则表达式忽略$VERSION
中的空行仅处理包含数字后跟点的行。当然,在每行中设置OFS有点笨拙,“+=1
”可以缩写为“++
”,因此您可以使用:
awk -F. '/[0-9]+\./{$NF++;print}' OFS=. <<< "$VERSIONS"
(或者你可以在程序中加入'BEGIN{OFS="."}
',但这相当冗长。
'<<<
'表示法仅由Bash支持,而不是由Korn,Bourne或其他POSIX shell支持(除非作为与Bash表示法并行的非标准扩展名)。任何版本的awk
都可以支持AWK程序,但是旧的UNIX 7th Edition AWK不支持命令行上的变量赋值。
答案 1 :(得分:5)
我想出了这个。
VERSIONS="
1.2.3.4.4
1.2.3.4.5.6.7.7
1.9.9
1.9.0.9
"
for VERSION in $VERSIONS; do
echo $VERSION | awk -F. '{$NF = $NF + 1;} 1' | sed 's/ /./g'
done
答案 2 :(得分:2)
if [[ "$VERSION" == *.* ]]; then
majorpart="${VERSION%.*}."
else
majorpart=""
fi
minorpart="${VERSION##*.}"
NEXT_VERSION="$majorpart$((minorpart+1))"
警告:如果版本号的次要部分不是预期格式(整数,没有前导零),则可能有问题。一些例子:“1.033” - &gt; “1.28”(因为033是27的八进制),“1.2.b” - &gt; “1.2.1”(除非b是定义的变量,它将被视为0),“1.2.3a” - &gt;错误(“3a”不是数字)。根据您想要覆盖的案例数量,这可以是任意复杂的。
答案 3 :(得分:0)
好吧,Jonathan Leffler已经answered这个问题,但是我已经推广了接受任意差异(作为awk参数versionDiff
传递)的解决方案:
VERSION="1.4.1.2"
awk -v versionDiff="0.1" -F. -f bump.awk OFS=. <<< "$VERSION"
结果将是:
1.5.0.0
因为上一个非零versionDiff编号之后的数字被清零。
和bump.awk
:
/[0-9]+\./ {
n = split(versionDiff, versions, ".")
if(n>NF) nIter=n; else nIter=NF
lastNonzero = nIter
for(i = 1; i <= nIter; ++i) {
if(int(versions[i]) > 0) {
lastNonzero = i
}
$i = versions[i] + $i
}
for(i = lastNonzero+1; i <= nIter; ++i) {
$i = 0
}
print
}