游客发表

powershell 重命名文件

发帖时间:2026-10-17 05:01:37

PowerShell 重命名文件,重命这事比你想的名文简单,也比你想的重命坑多。别急着写脚本,名文先明白一个核心事实:Rename-Item 是重命唯一靠谱的原生命令,但它的名文参数设计得让人想骂娘。

你打开 PowerShell,重命敲 Rename-Item old.txt new.txt,名文文件就改了。重命但如果你要批量改,名文比如把一堆 photo_2024.jpg 改成 2024-01-01.jpg 这种带日期的重命,直接写循环?名文行,但你得先处理一个破事:Rename-Item 的重命 -NewName 参数不支持通配符。什么意思?名文你写 Rename-Item *.jpg *.bak,它直接报错,重命说找不到路径。

我当年第一次用这命令时,愣是卡了十分钟。后来才明白,你得配合 Get-ChildItem 管道传对象,再在 -NewName 里用 $_ 动态生成新名字。比如:

Get-ChildItem *.jpg | Rename-Item -NewName {  $_.BaseName + "_backup" + $_.Extension }

这段代码把每个 jpg 文件改成原名加 _backup 后缀。注意,花括号里是脚本块,PowerShell 会自动把当前文件对象丢进去。这招比写 for 循环干净多了。

但真正的坑在编码和特殊字符。文件名里有空格?有方括号?PowerShell 会把 [ 当通配符处理,导致找不到文件。你得用 -LiteralPath 参数。举个真实案例:我同事有批文件叫 report[final].docx,直接 Rename-Item 报错,加上 -LiteralPath 就秒改。这破问题网上搜半天都搜不到,因为大部分人文件名里没方括号。

再聊个高级玩法:正则替换文件名。假设你要把所有 IMG_20240101_123456.jpg 改成 2024-01-01.jpg,光靠 BaseName 不够,得用 -replace 操作符:

Get-ChildItem IMG_*.jpg | Rename-Item -NewName {  $_.Name -replace 'IMG_(\d{ 4})(\d{ 2})(\d{ 2})_.*\.jpg', '$1-$2-$3.jpg' }

这正则看着吓人,但拆开就懂:(\d{ 4}) 抓四位年份,后面两位月份两位日期,最后 .*\.jpg 吞掉剩余部分。替换成 $1-$2-$3 就是 2024-01-01。实际用的时候,我建议先加 -WhatIf 参数测试,它会打印将要执行的操作而不真改文件。这习惯救了我好几次,尤其批量操作前,看一遍输出比事后后悔强。

最后说个冷门但实用的:重命名文件夹。很多人不知道 Rename-Item 同样适用,但如果你要改的文件夹正在被其他程序占用(比如资源管理器开着),会报错。解决办法是关掉那个窗口,或者用 cmd /c ren 绕过去。PowerShell 有时候太“安全”了,反而让人抓狂。

对了,还有个小技巧:Rename-Item 支持 -PassThru 参数,返回重命名后的文件对象。配合 ForEach-Object 可以在改完后立刻做下一步操作,比如移动文件或改属性。比如:

Get-ChildItem temp_*.txt | Rename-Item -NewName {  $_.Name -replace '^temp_', '' } -PassThru | Move-Item -Destination .\archive

这一行把临时文件去掉前缀,然后直接挪进归档文件夹。省了中间变量,代码紧凑但可读性还行。不过说实话,这种链式写法超过两个管道我就得加注释,不然下个月自己看都懵。

写脚本时记住一个原则:先小范围测试,再全量执行。拿三个文件试,确认无误后去掉 -WhatIf 跑全量。另外,文件名里尽量别用中文和特殊符号,不是 PowerShell 不行,是 Windows 文件系统本身对某些字符敏感(比如冒号、问号)。如果必须处理,用 [System.IO.Path]::GetInvalidFileNameChars() 检查一下字符合法性。

重命名这活,看着低级,但做不好真能毁数据。有一次我写错正则,把几百个文件的前缀全删了,还好有备份。所以,备份、测试、再执行,这顺序别乱。PowerShell 给的自由度大,犯错成本也大,但掌握好了,效率提升是肉眼可见的。

    热门排行

    友情链接