如何用PowerShell正则判断文件名末尾是否含指定格式日期
问题描述
- 有一组每日更新的SSRS报表文件夹,SSRS不支持在文件名末尾追加下划线及创建日期。
- 已写好PowerShell命令,原本是把修改日期追加到文件名开头,现在要改成追加到末尾(这部分自己能调整)。
- 核心问题:没法识别文件名末尾已经有
_YYYYMMDD格式日期的文件,导致重复加日期。 - 规则:
- 文件名长度不固定
- 目标日期格式是
_YYYYMMDD,最终文件名要改成FileName_YYYYMMDD.xlsx - 文件必须留在原文件夹,不能移走
当前用的脚本:
$ParsedDate = [datetime]::MinValue; $Path = "C:\UserDocuments\Config Updates"; Get-ChildItem -File -Path $Path | Where-Object { (-not [regex]::IsMatch($_.Name, "^\d{8}_", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)) -or (-not [datetime]::TryParseExact($_.Name.Substring(0, 8), "yyyyMMdd", [cultureinfo]::CurrentCulture, [System.Globalization.DateTimeStyles]::None, [ref] $ParsedDate)) } | ForEach-Object { Rename-Item -Path ($_.FullName) -NewName "$($_.BaseName)_$($_.LastWriteTime.ToString("yyyyMMdd"))$($_.Extension)";}
试过调整正则比如"^\d{8}_"、"^_\d{8}"、"^\d{8}"都没用,需要正确的正则写法。
解决方案
要识别文件名末尾是否已经有_YYYYMMDD格式的日期,得匹配文件名(不含扩展名)的末尾是否符合规则,正确的正则表达式是:_(\d{8})$
修改后的完整脚本
$ParsedDate = [datetime]::MinValue; $Path = "C:\UserDocuments\Config Updates"; Get-ChildItem -File -Path $Path | Where-Object { # 检查文件名(不含扩展名)末尾是否有_YYYYMMDD格式,同时验证日期有效性 (-not [regex]::IsMatch($_.BaseName, "_(\d{8})$")) -or (-not [datetime]::TryParseExact($matches[1], "yyyyMMdd", [cultureinfo]::CurrentCulture, [System.Globalization.DateTimeStyles]::None, [ref] $ParsedDate)) } | ForEach-Object { Rename-Item -Path $_.FullName -NewName "$($_.BaseName)_$($_.LastWriteTime.ToString("yyyyMMdd"))$($_.Extension)" }
关键说明
- 正则
_(\d{8})$的作用:_:匹配下划线(\d{8}):捕获8位数字(对应YYYYMMDD格式)$:定位到文件名(不含扩展名)的末尾,确保日期是最后一部分
- 用
$_.BaseName来匹配,因为它不包含文件扩展名,避免把扩展名里的数字误判成日期 - 保留
TryParseExact是为了验证捕获到的8位数字确实是有效的日期,比如不会把99999999这种无效格式当成合法日期
内容的提问来源于stack exchange,提问作者Rob Halls
相关产品推荐
相关产品推荐

