如何用PowerShell脚本按文件名年月分组归档旧文件(保留近2个月)
基于文件名日期的文件归档脚本实现
需求回顾
需要归档数千份跨年度文件,规则如下:
- 从文件名(格式如
ABCXYZ_20220715.xml)提取年月信息,不依赖文件修改/创建时间 - 保留最近2个月的文件,仅归档早于该时间范围的文件
- 归档结构按「年→月」嵌套,最终将对应年月的文件压缩为ZIP包
修改后的完整脚本
# 计算归档截止日期:取当前月第一天往前推2个月,确保保留最近2个月的文件 $today = [datetime]::Today $cutoffDate = (Get-Date -Year $today.Year -Month $today.Month -Day 1).AddMonths(-2) $SourceFolder = "C:\Temp\sent" $DestinationFolder = "C:\Temp\Archive" # 筛选符合命名规则且需归档的文件,按文件名年月分组 $filesByMonth = Get-ChildItem -Path $SourceFolder -File | ForEach-Object { # 匹配文件名中的8位日期段(下划线后、扩展名前) if ($_.Name -match '_(\d{8})\.') { $fileDateStr = $matches[1] # 严格解析为yyyyMMdd格式的日期 if ([datetime]::TryParseExact($fileDateStr, "yyyyMMdd", $null, [System.Globalization.DateTimeStyles]::None, [ref]$fileDate)) { # 仅保留文件名日期早于截止日期的文件 if ($fileDate -lt $cutoffDate) { [PSCustomObject]@{ File = $_ YearMonth = $fileDate.ToString("yyyy\\MM") } } } } } | Group-Object -Property YearMonth # 批量处理每个年月组的归档与压缩 foreach ($monthlyGroup in $filesByMonth) { $archiveFolder = Join-Path $DestinationFolder $monthlyGroup.Name # 自动创建年/月嵌套目录 New-Item -Path $archiveFolder -ItemType Directory -Force | Out-Null # 将文件移动到对应年月目录 $monthlyGroup.Group.File | Move-Item -Destination $archiveFolder -Force # 压缩目录为同名ZIP(自动添加.zip后缀) Compress-Archive -Path $archiveFolder -DestinationPath $archiveFolder -Force # 删除临时存放文件的目录 Remove-Item $archiveFolder -Recurse -Force }
关键修改说明
- 日期提取逻辑:
- 用正则表达式
_(\d{8})\.精准匹配文件名中的日期部分,避免误解析其他数字 - 通过
TryParseExact严格校验日期格式,跳过不符合规则的文件,提升脚本鲁棒性
- 用正则表达式
- 截止日期计算:
- 取当前月的第一天再往前推2个月,确保最近2个月(例如当前为10月时,保留9、10月文件,归档8月及更早)
- 分组与归档:
- 按文件名解析出的
yyyy\MM路径分组,自动创建嵌套的年/月目录 - 移动文件后压缩为对应年月的ZIP包,再删除临时目录,最终归档结构为
归档根目录\年份\月份.zip
- 按文件名解析出的
- 鲁棒性优化:
- 加入
-Force参数处理文件/目录覆盖场景 - 过滤无效文件名,避免脚本因格式错误中断
- 加入
内容的提问来源于stack exchange,提问作者Dinav Ahire
相关产品推荐
相关产品推荐

