在 PowerShell [Core] (v6.1+) 中,可以使用简洁的解决方案:
$file = 'somefile.txt'
(Get-Content -Raw $file) -replace '(?m)(?<=^\s+version: ).+(?=;$)', {
# Increment the *last numeric* component of the version number.
# See below for how to target other components.
$_.Value -replace '(?<=\.)\d+(?=$|-)', { 1 + $_.Value }
} | Set-Content $file
注意:
* 在 PowerShell [Core] 6+ 中,无 BOM 的 UTF-8 是默认编码;如果您需要不同的编码,请使用 -Encoding 和 Set-Content。
* 通过使用-Raw,该命令首先将整个文件读入内存,从而可以在同一管道中回写同一文件;但是,如果写回输入文件被中断,则存在轻微的数据丢失风险。
* -replace 总是替换 all 匹配正则表达式的子字符串。
* 内联正则表达式选项(?m) 确保^ 和$ 匹配个别行 的开始和结束,这是必要的,因为Get-Content -Raw 将整个文件作为单个、多行读取线串。
注意:
为简单起见,基于文本对版本字符串进行操作,但您也可以将 $_.Value 转换为 [version] 或 [semver] (仅限 PowerShell [Core] v6+)并使用它。
基于文本的操作的优点是能够简洁地保留输入版本字符串的所有其他组件,而无需添加以前未指定的组件。
以上内容依赖于-replace operator 通过脚本块 ({ ... }) 完全动态执行基于正则表达式的字符串替换的能力 - 如this answer 中所述.
-
正则表达式使用look-around assertions((?<=...)和(?=...)),以确保只匹配要修改的输入部分。
- 只有
(?<=^\s+version: ) 和(?=;$) 环视是特定于示例文件格式的;根据需要调整这些部分以匹配文件格式中的版本号。
上述增量是输入版本的最后一个数字组件。
要定位各种版本号组件,请改用以下内部正则表达式:
-
增加主要数字(例如,2.0.9 -> 3.0.9):
'2.0.9' -replace '\d+(?=\..+)', { 1 + [int] $_.Value }
-
次要数:
'2.0.9' -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
-
patch / build 编号(第三个组件;2.0.9 -> 2.0.10):
'2.0.9' -replace '(?<=^\d+\.\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
-
last / revision 编号,如上,不管它是什么,即使后面跟着一个预发布标签(例如,; 2.0.9.10 -> 2.0.9.11 或 7.0.0-preview2 -> 7.0.1-preview2):
'2.0.9.10' -replace '(?<=\.)\d+(?=$|-)', { 1 + [int] $_.Value }
注意:如果目标组件不存在,则原样返回原始版本。
在 Windows PowerShell 中,-replace 不支持基于脚本块的替换,您可以将 switch 语句与 -File 和 -Regex 选项一起使用:
$file = 'someFile.txt'
$updatedFileContent =
switch -regex -file $file { # Loop over all lines in the file.
'^\s+version: (.+);$' { # line with version number
# Extract the old version number...
$oldVersion = $Matches[1]
# ... and update it, by incrementing the last component in this
# example.
$components = $oldVersion -split '\.'
$components[-1] = 1 + $components[-1]
$newVersion = $components -join '.'
# Replace the old version with the new version in the line
# and output the modified line.
$_.Replace($oldVersion, $newVersion)
}
default { # All other lines.
# Pass them through.
$_
}
}
# Save back to file. Use -Encoding as needed.
$updatedFileContent | Set-Content $file