Powershell 将名称中带有时间戳的文件移动到 year/month 个文件夹中

Powershell move files with timestamp in name into year/month folders

我有很多半小时文件的名称格式为 A_B_C_YYYYMMDDThhmm_YYYYMMDDThhnn.csv A、B、C是单词 其中 YYYY 是 4 位数的年份, MM 2 位数的月份, DD 两位数的月份日期, hh 一天中的小时,以 2 位数字表示, mm 2 位数的分钟, 而nn是mm+30分钟

如何使用 Powershell 将这些文件移动到基​​于年份和月份的文件夹中?

我已经尝试基于以前使用的 但它没有为我的文件名格式生成任何输出,大概是因为 match 字符串是错误的:

Push-Location 'path/to/files'
Get-ChildItem _*_*.csv |
  Where-Object {$_.BaseName -match '_(\d{4})(\d{2})T(\d{4})_\d{6}T(\d{4})'} | ForEach-Object {
    $TargetDir = "{0}\{1}" -f $Matches[1],$Matches[2]
    if (!(Test-Path $TargetDir)){MD $TargetDir | Out-Null}
    $_ | Move -Destination $TargetDir 
}

乍一看,您的正则表达式模式与您推测的不匹配。我更改了 pattern a bit, and using [datetime]::ParsedExact(..) 以提取年份和月份。之前没有测试过,但我相信它应该可以工作。

不用说,这段代码没有处理文件冲突,如果有一个文件与正在移动到目标的文件之一同名,这将失败。

Push-Location 'path/to/files'

Get-ChildItem -Filter _*_*.csv | ForEach-Object {
    if($_.BaseName -match '(?:\w_){3}(\d{8})T\d{4}_T\d{4}') {
        $parsed = [datetime]::ParseExact(
            $Matches[1], 'yyyyMMdd', [cultureinfo]::InvariantCulture
        )
        $folder = '{0:0000}\{1:00}' -f $parsed.Year, $parsed.Month
        $path = Join-Path $PWD.Path -ChildPath $folder
        if(-not (Test-Path $path)) {
            $null = New-Item $path -ItemType Directory
        }
        
        Move-Item -LiteralPath $_.FullName -Destination $path
    }
}