[英]Increment a version number contained in a text file
這個自我回答的問題解決了最初在文件中的增量版本號中描述的場景:
嵌入在文本文件中的版本號將遞增。
示例文本文件內容:
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
- 同上,另外還有一個+
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-less UTF-8 是默認編碼; 如果您需要不同的編碼,請使用-Encoding
和Set-Content
。
* 通過使用-Raw
,該命令首先將整個文件讀入內存,這樣可以在同一管道中寫回同一文件; 但是,如果寫回輸入文件被中斷,則存在數據丟失的輕微風險。
* -replace
總是替換與正則表達式匹配的所有子字符串。
* 內聯正則表達式選項(?m)
確保^
和$
匹配各個行的開始和結束,這是必要的,因為Get-Content -Raw
將整個文件作為單個多行字符串讀取。
筆記:
為簡單起見,對版本字符串執行基於文本的操作,但您也可以將$_.Value
為[version]
或[semver]
(僅限 PowerShell [Core] v6+)並使用它。
基於文本的操作的優點是能夠按原樣保留輸入版本字符串的所有其他組件,而無需添加以前未指定的組件。
以上依賴於-replace
運算符通過腳本塊( { ... }
) 完全動態地執行基於正則表達式的字符串替換的能力 - 如本答案所述。
正則表達式使用環視斷言( (?<=...)
和(?=...)
)以確保僅匹配要修改的輸入部分。
(?<=^\\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 }
補丁/內部版本號(第三個組件; 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中,其中-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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.