2017-07-06 41 views
0

我有用yyyymm命名的文件,我需要用mmyyyy重命名這個文件,但新名稱中的mm必須少於一個。我需要在更換過程中進行聯機。Powershell:使用內聯計算的正則表達式替換

我可以做圖形字符串的正則表達式替換abc201706.txtabc062017.txt

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

我該怎麼辦正則表達式替換爲abc052017.txt
換句話說,我需要從$3的一個月內聯扣除,這意味着最初的月份。

我已經搜索了我的問題的答案很多帖子,但沒有結果。請不要將我的問題標記爲重複並回答。

+1

我會做幾行,可能無需替換。只需''匹配'basename',利用'$ matches'並做你的計算。之後,再次使用'-f'運算符構建基本名稱字符串。 – restless1987

+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:\嗒嗒」

+0

酷,但我需要在一行/ –

+0

嗯,我們可以使這是一個oneliner ...但它將是荒謬的漫長。爲什麼你需要它作爲一個線索?把它作爲一個函數來實現呢? – restless1987

+0

呵呵,當然,我可以將這段代碼拉伸到一行,但它絕對不可讀) –

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組的六個數字的日期時間,減去一個月,再一起把一切都回來了。

catch塊只是在轉換爲DateTime失敗的情況下輸出原始匹配。