Powershell:使用内联计算替换正则表达式

时间:2017-07-06 06:33:05

标签: regex powershell

我有以yyyymm命名的文件,我需要使用mmyyyy重命名这些文件,但新名称中的mm必须少于一个。我需要在更换过程中内联。

我可以将字符串abc2017 06 .txt的正则表达式替换为abc 06 2017.txt带模式

  

'abc201706.txt' -replace '^(.*)([0-9]{4})([0-9]{2})(\..*)$','$1$3$2$4'

如何将正则表达式替换为abc 05 2017.txt? 换句话说,我需要从$3开始一个月的内联减法,这意味着初始月份。

我在很多帖子中搜索了我的问题的答案但没有结果。请不要将我的问题标记为重复并回答它。

2 个答案:

答案 0 :(得分:1)

没有美,但应该有效:

$myfilepath = 'C:\temp\abc2017 06.txt'
$file = Get-Item $myFilePath -Force 
$basename = $file.basename

$basename -match '^(?<name>\D+)(?<year>\d{4})\s(?<month>\d{2})'

$dateString = "{0}/{1}/01" -f $matches.year, $matches.month
$Datetime = $dateString | Get-Date
$Datetime = $Datetime.AddMonths(-1)

$newBasename = "{0} {1} {2}{3}" -f $matches.name, $Datetime.ToString('MM'), $Datetime.ToString('yyyy'), $file.Extension

更新:您的正则表达式不匹配,我稍微改了一下。

Update2 :将此内容写入文件,然后根据需要调用它。

param(
    [string]$myFilePath
)
$file = Get-Item $myFilePath -Force 
$basename = $file.basename

$null = $basename -match '^(?<name>\D+)(?<year>\d{4})\s(?<month>\d{2})'

$dateString = "{0}/{1}/01" -f $matches.year, $matches.month
$Datetime = $dateString | Get-Date
$Datetime = $Datetime.AddMonths(-1)

$newFilename = "{0} {1} {2}{3}" -f $matches.name, $Datetime.ToString('MM'), $Datetime.ToString('yyyy'), $file.Extension

return $newFilename

例如:ConvertFilename.ps1 -myFilePath“c:\ Blah”

答案 1 :(得分:1)

一种方法是使用.NET正则表达式match evaluators,基本上是可以计算替换值的回调函数。

Powershell脚本块可用作匹配评估程序。它们接收匹配对象作为第一个参数,它们产生的值将用作替换。

Get-ChildItem -Filter "*.txt" | Foreach-Object {
    $_.Name = [Regex]::Replace($_.Name, "(\d{6})(\.txt)$", {
        $match = $args[0]
        try {
            [DateTime]::ParseExact($match.Groups[1], "yyyyMM", $null).AddMonths(-1).ToString("MMyyyy") + $match.Groups[2]
        } catch {
            $match
        }
    })
}

try块尝试将匹配组1中的六位数字解析为DateTime,减去一个月并将所有内容重新组合在一起。

如果转换为DateTime失败,catch块只会输出原始匹配。