首页 > 解决方案 > Powershell:在忽略字符串标签的同时增加数字

问题描述

这是我的第一个堆栈问题,所以请放轻松。

目前正在进行一个项目,通过增加以前的文件夹版本号在网络驱动器上创建一个新文件夹。

例如: 5.2.0.0110->5.2.0.0111

这是我当前的 powershell 解决方案,可以解决问题:

$SourceFolder = "\\corpfs1\setup\ProtectionSuite\Version 5.2.0.x\5.2.0.0001"
$DestinationFolder = "\\corpfs1\setup\ProtectionSuite\Version 5.2.0.x"
$msiSourceFolder = "\\SourceMsiPath"
$exeSourceFolder = "\\SourceExePath"
if (Test-Path $SourceFolder)
{
        $latest = Get-ChildItem -Path $DestinationFolder| Sort-Object Name -Descending | Select-Object -First 1 
        #split the latest filename, increment the number, then re-assemble new filename:
        $newFolderName = $latest.BaseName.Split('.')[0] + "." + $latest.BaseName.Split('.')[1] + "."+ $latest.BaseName.Split('.')[2] + "." + ([int]$latest.BaseName.Split('.')[3] + 1).ToString().PadLeft(4,"0")
        New-Item -Path $DestinationFolder"\"$newFolderName -ItemType Directory

        Copy-Item $msiSourceFolder -Destination $DestinationFolder"\"$newFolderName
        Copy-Item $exeSourceFolder -Destination $DestinationFolder"\"$newFolderName
}

但是,这不考虑的一件事是最后带有字符串的版本号。此解决方案尝试隐藏失败的字符串 -> int。一些文件夹具有用于内部版本的字符串,因此无法仅更改我的命名语义。

例如:5.2.0.1234 (eng)->5.2.0.1235

我想忽略最后四位数字之后的任何文本并递增,如上面的示例所示。如果有人有建议,我会全力以赴!谢谢你。

标签: powershelltext-parsing

解决方案


假设您的文件夹名称仅包含一个以 a 开头的 4 位序列,则使用基于正则表达式运算符和基于脚本块.的替换更简单地匹配和替换-replace

更新

  • 后来的澄清表明,输入字符串中的后期版本后缀应该(b)从输出中删除,而不是(a)只是为了增加而忽略,同时保留在输出中 - 请参阅底部的解决方案(b)。

解决方案(a):如果应保留后版本后缀:

在 PowerShell (Core) v6.1+ 中:

# Replace the sample value '5.2.0.1234 (eng)' with the following in your code:
#   $newFolderName = $latest.BaseName [-replace ...]
'5.2.0.1234 (eng)' -replace '(?<=\.)\d{4}', { '{0:0000}' -f  (1 + $_.Value) }

上面的产量5.2.0.1235 (eng)- 注意增加的最后一个版本号组件和后缀的保留

在不支持基于脚本块的替换的Windows PowerShell(最高 5.1 版本)中,需要直接使用底层 .NET API:

[regex]::Replace('5.2.0.0110 (eng)', '(?<=\.)\d{4}', { '{0:0000}' -f  (1 + $args[0].Value) })

说明

  • (?<=\.)\d{4}是一个正则表达式(正则表达式),它与后向断言 ( ) 中的文字.( ) 匹配,后跟 4 个 ( ) 数字 ( )。后视断言确保文字包含在匹配捕获的文本中。\.(?<=...){4}\d.

  • 脚本块 ( ) 作为一个实例,通过PowerShell (Core) 解决方案中的自动变量,通过直接.NET调用的 Windows PowerShell 解决方案中的自动变量{ ... },接收有关(每个)匹配的信息。System.Text.RegularExpressions.Match$_$args

  • 脚本块的输出(返回值)用于替换匹配的文本:

    • '{0:0000}' -f ...使用-f格式运算符,使用 4 位填充来格式化 RHS 0

    • (1 + $_.Value)/(1 + $args[0].Value)添加1到匹配捕获的 4 位序列,由于操作的 LHS 是数字,因此隐式+转换为数字。


解决方案(b):如果应该删除后版本后缀:

在 PowerShell (Core) v6.1+ 中:

'5.2.0.1234 (eng)' -replace '\.(\d{4}).*', { '.{0:0000}' -f  (1 + $_.Groups[1].Value) }

上面的产量5.2.0.1235- 注意增加的最后一个版本号组件和没有后缀。

在 Windows PowerShell 中

[regex]::Replace('5.2.0.1234 (eng)', '\.(\d{4}).*', { '.{0:0000}' -f  (1 + $args[0].Groups[1].Value) })

推荐阅读