powershell - 增加文本文件中包含的版本号
问题描述
这个自我回答的问题解决了最初在文件中增加版本号中描述的场景:
嵌入在文本文件中的版本号将递增。
示例文本文件内容:
nuspec{
id = XXX;
version: 0.0.30;
title: XXX;
例如,我希望将嵌入式版本号0.0.30
更新为0.0.31
.
可以假设感兴趣的行与以下正则表达式匹配:^\s+version: (.+);$
请注意,目的不是用固定的新版本替换版本号,而是增加现有版本。
[version]
理想情况下,增量逻辑将处理表示( System.Version
) 或[semver]
( ) 实例的版本字符串System.Management.Automation.SemanticVersion
,范围从 2 到 4 个组件;例如:
1.0
1.0.2
1.0.2.3
-[version]
格式(最多 4 个数字组件)1.0.2-preview2
-[semver]
格式(最多 3 个数字组件),可选择使用 - 分隔的-
预览标签1.0.2-preview2+001
- 同上,另外带有 -+
分隔的构建标签
解决方案
在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
with 。
* 通过使用,该命令首先将整个文件读入内存,从而可以在同一管道中回写同一文件;但是,如果写回输入文件被中断,则存在轻微的数据丢失风险。
*总是替换与正则表达式匹配的所有子字符串。
* 内联正则表达式选项确保并匹配各个行的开头和结尾,这是必要的,因为将整个文件作为单个多行字符串读取。
Set-Content
-Raw
-replace
(?m)
^
$
Get-Content -Raw
笔记:
为简单起见,对版本字符串执行基于文本的操作,但您也可以
$_.Value
转换为[version]
or[semver]
(仅限 PowerShell [Core] v6+)并使用它。
基于文本的操作的优点是能够简洁地保留输入版本字符串的所有其他组件,而无需添加以前未指定的组件。以上依赖于
-replace
操作员通过脚本块({ ... }
) 完全动态地执行基于正则表达式的字符串替换的能力 - 如本答案中所述。正则表达式使用环视断言(
(?<=...)
and(?=...)
) 以确保仅匹配要修改的输入部分。- 只有
(?<=^\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 }
补丁/内部版本号(第3 个组件;
2.0.9
->2.0.10
):'2.0.9' -replace '(?<=^\d+\.\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
最后/修订号,如上,不管它是什么,即使后面跟着一个预发布标签(例如,; -
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中,您可以使用带有and选项的语句:-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
推荐阅读
- python - 如何复制熊猫数据框以匹配其他数据框的长度?
- android - ClassNotFoundException:找不到类“kotlin.jvm.internal.Lambda”
- php - 如何使用 php、ajax、jquery 和下拉菜单使页面以正确的顺序显示产品
- python - 具有多个守护进程的 Apache mod_wsgi 内存缓存
- geospatial - 如何在 Google 地球引擎上可视化上传的图像
- docker - 将 SoftHSM 库暴露给在主机中运行的代码
- sql-server - 用于操作 SQL 备份的 DevOps 或 SQLDataFactory 管道
- azure - 不支持输入 URI 的方案
- ansible - 在 Satellite 6.4 中未找到任何 ansible 角色 - 已安装系统角色
- excel - 如何使用 VBA 在指定范围内选择与另一个单元格的值匹配的单元格?