VERSION=1.9.0.9
NEXT_VERSION=1.9.0.10
编辑:版本号仅包含自然数。
解决方案是否可以通用化以处理版本号中的任意部分。
例如:
1.2
1.2.3
1.2.3.4
1.2.3.4.5
简而言之:
VERSION=1.9.0.9
echo $VERSION | awk -F. '/[0-9]+\./{$NF++;print}' OFS=.
# will print 1.9.0.10
如需详细解释,请继续阅读。
让我们从基础开始,froogz3301提供了answer:
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
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 第七版 AWK 的支持)。
我想出了这个。
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
awk -F. '/[0-9]+\./{$NF++;print}' OFS=. <<< "$VERSIONS"
(或者你可以在程序中包含'BEGIN{OFS="."}
',但那太啰嗦了)。 - Jonathan Lefflerprint
。它与前置的1不同,前者仅选中输入的第一行。对于递增,$NF++
也可以使用。您只需要设置一次输出定界符。结果:awk -F. '{$NF++}1' OFS=.
或awk -F. '1{$NF++}1' OFS=.
。虽然我更喜欢显式打印而不是隐式打印,但是$0
并不必要:awk -F. '{$NF++; print}' OFS=.
。OFS
也可以通过-v
参数或在BEGIN
语句中进行设置。我看到你说了我正在打字的几件事情。 - Dennis Williamsonawk -F. '{$NF++}"print"' OFS=.
... 哦,等等... ;) - Dennis Williamsonif [[ "$VERSION" == *.* ]]; then
majorpart="${VERSION%.*}."
else
majorpart=""
fi
minorpart="${VERSION##*.}"
NEXT_VERSION="$majorpart$((minorpart+1))"
警告:如果版本号的次要部分不符合预期格式(整数,没有前导零),可能会出现问题。一些例子:"1.033" -> "1.28"(因为 033 是 27 的八进制表示),"1.2.b" -> "1.2.1"(除非 b 是一个已定义的变量,否则它将被视为 0),"1.2.3a" -> 错误("3a" 不是一个数字)。根据您想要涵盖的情况数量,这可以变得任意复杂。
NEXT_VERSION="$majorpart$((10#$minorpart+1))"
,这样“033”将变成“34”。这样做是个好主意,因为“038”会产生错误。但是,它会导致你的“b”示例产生错误。 - Dennis Williamson好的,Jonathan Leffler已经 回答了这个问题,但我将解决方案推广到接受任意差异(通过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
}
## bump-%: bump the % chart version number bump-%: docs lint update-deps @echo "$$(awk -F. '{if ($$0 ~ /version: [0-9]+\./) {$$NF++;print} else {print}}' OFS=. $(CHARTS_FOLDER)/$*/Chart.yaml)" > $(CHARTS_FOLDER)/$*/Chart.yaml
- Luis Davim