
最近好几个朋友跑来问我同一个问题怎么把文件夹里上百个文件名里的大写字母变小写他们有的是做前端项目的从Windows上拷出来的图片资源一部署到Linux服务器就报404有的只是整理网盘资料想统一命名规则方便搜索。我帮他们踩了一遍所有常见的办法最后沉淀下来4个亲测有效、覆盖Windows和Linux/macOS的批量改小写方案。这篇文章就把每个方法的操作步骤、适用场景和坑全部写出来从双击即用的BAT脚本到一行命令的PowerShell再到图形化工具总有一款适合你。这个需求看起来简单但实际操作里有个容易被忽视的点Windows文件名大小写不敏感Linux和很多代码仓库却非常敏感资源文件一旦对不上号引用路径直接挂掉。所以“文件名统一小写”不只是强迫症更是一个跨平台协作时的刚需。1. 先想明白为什么要统一小写以及方案怎么选1.1 几个真实会遇到的问题我大概梳理了一下想批量把文件名改成小写的人通常逃不过这几种场景跨平台部署很多项目在Windows上开发和上传资料但服务器是Linux。Linux文件系统严格区分大小写如果你的代码里引用了logo.png实际文件名却是Logo.PNG部署阶段就会在别人电脑上莫名其妙报错。Git仓库协作Git本身会追踪文件名大小写但老版本Git在Windows默认配置下不完全区分大小写。团队成员一个提交README.md、一个提交Readme.md仓库里就会出现两个看似相同但实际不同的文件合代码时特别痛苦。归档排序资料盘里的扫描件、截图经常大小写混乱比如Report_Final_V2.PDF、report_final_v2.pdf。统一成全小写后按字典序排列会规整很多用关键词检索也更快。脚本依赖后缀名很多批处理脚本、上传工具在识别.jpg、.png、.mp4时只认小写后缀文件后缀带大写字母就会漏处理。1.2 四种方案的选型思路方案适用平台难度适合谁CMD批处理脚本Windows偏低不想装额外软件一次处理当前目录PowerShell命令Windows中等需要递归子目录、处理中文、或想先预览Linux/macOS的rename或shell循环Linux/macOS中等服务器、开发环境、macOS终端图形化批量改名工具Windows/macOS很低想可视化操作、需要预览和组合多种改名规则这四个方案我都实际跑过。在Windows上日常排查、递归处理我优先用PowerShell在服务器上或者自动化脚本里我会用Linux的rename命令给完全不懂命令行的人推荐图形工具而BAT脚本适合快速处理某个固定文件夹尤其是公司内网的老旧Windows环境双击一下就搞定了。2. 方法一Windows下用批处理脚本一个BAT搞定大小写转换2.1 批处理脚本的原理Windows自带的ren命令可以重命名文件但CMD本身没有内置“转小写”的函数。常规思路是用for循环遍历当前目录所有文件再通过变量替换把26个大写字母逐个替换成小写字母。这里需要注意CMD的一个特性普通变量%name%在for循环体里每次都会重新展开成初始值所以必须用setlocal EnableDelayedExpansion开启延迟变量扩展循环内才可以用!name!取值。脚本的核心就是set name!name:Aa! set name!name:Bb!set命令的字符串替换语法是set 变量变量:被替换内容替换内容把A替换成a把B替换成b一直写到Zz。2.2 完整脚本与使用步骤你只需要新建一个文本文件把下面内容粘贴进去保存后把扩展名改成.batecho off setlocal EnableDelayedExpansion cd /d %~dp0 for /f delims %%i in (dir /b /a-d) do ( set name%%i set name!name:Aa! set name!name:Bb! set name!name:Cc! set name!name:Dd! set name!name:Ee! set name!name:Ff! set name!name:Gg! set name!name:Hh! set name!name:Ii! set name!name:Jj! set name!name:Kk! set name!name:Ll! set name!name:Mm! set name!name:Nn! set name!name:Oo! set name!name:Pp! set name!name:Qq! set name!name:Rr! set name!name:Ss! set name!name:Tt! set name!name:Uu! set name!name:Vv! set name!name:Ww! set name!name:Xx! set name!name:Yy! set name!name:Zz! ren %%i !name! 2nul ) echo 处理完成。 pause使用步骤把脚本放到你想处理的文件夹里。双击运行当前目录下的所有文件不包含子文件夹都会把文件名和扩展名里的所有大写字母转成小写。如果改名出现冲突、文件被占用ren命令会静默跳过第二行的2nul把错误信息隐藏了。2.3 批处理脚本的注意点默认只处理当前目录不会进入子文件夹。如果需要递归用PowerShell更稳妥BAT递归写法比较绕后面会给你替代方案。文件名里如果包含英文感叹号!在进阶的重命名规则里可能会被解释成变量但使用EnableDelayedExpansion时要把!写成!!转义否则可能被吞字符。实测下来最常见的问题是文件被占用。如果文件名是中文请确保.bat文件保存为ANSI编码。用Windows记事本另存为时编码选择“ANSI”即可。千万不要存成UTF-8否则CMD读取出来的中文文件名可能变成乱码后面ren会找不到文件。提示首次运行前建议先复制一份文件到临时文件夹里测试。这个脚本完全依靠ren命令不会备份一旦出现重名冲突可能会跳过但其他能改的文件会正常处理所以提前确认最稳妥。3. 方法二PowerShell一行命令优雅且支持中文3.1 PowerShell为什么适合这种批量操作PowerShell在Windows 10/11里自带它处理文件对象比CMD灵活得多。批量重命名的核心思路是“管道”Get-ChildItem列出文件Where-Object过滤文件Rename-Item执行改名。和BAT脚本最大的区别是PowerShell原生支持Unicode中文文件名不会乱码而且能轻松递归整个目录树。如果要处理大量文件我一般直接用PowerShell而不是BAT。3.2 三条常用命令模板在当前文件夹直接打开PowerShell执行下面这条命令会把当前目录下所有文件名包含扩展名里的大写字母全部转成小写Get-ChildItem -Path . -File | Where-Object { $_.Name -cne $_.Name.ToLower() } | ForEach-Object { Rename-Item -LiteralPath $_.FullName -NewName $_.Name.ToLower() }解释一下关键点-cne是“区分大小写的不等于”相当于先判断一下文件名和它的小写版本是否不同。如果不同才改名这样可以减少无效操作。-LiteralPath是为了避免文件名里含有方括号[]时被PowerShell当成通配符。如果只想把主文件名转成小写保留扩展名不变用这条Get-ChildItem -Path . -File | ForEach-Object { if ($_.BaseName -cne $_.BaseName.ToLower()) { $newName $_.BaseName.ToLower() $_.Extension Rename-Item -LiteralPath $_.FullName -NewName $newName } }如果需要递归处理所有子目录只要在Get-ChildItem后面加一个-Recurse参数Get-ChildItem -Path . -Recurse -File | Where-Object { $_.Name -cne $_.Name.ToLower() } | ForEach-Object { Rename-Item -LiteralPath $_.FullName -NewName $_.Name.ToLower() }3.3 先预览再执行避免手抖我强烈建议你在真正执行之前先加一个-WhatIf参数看看效果。-WhatIf的意思是“模拟执行”PowerShell会列出它将执行的操作但不会真的改文件名Get-ChildItem -Path . -Recurse -File | Where-Object { $_.Name -cne $_.Name.ToLower() } | ForEach-Object { Rename-Item -LiteralPath $_.FullName -NewName $_.Name.ToLower() -WhatIf }运行后检查输出确认没有意外情况再把-WhatIf删除正式执行。经验之谈在几百个文件面前我从来不会直接执行。就算是自己写的命令也可能因为$_.Extension包含了大写后缀导致结果和预期不符。多花5秒预览能省掉后面恢复文件名的半小时。4. 方法三Linux/macOS下用rename或shell循环处理4.1 两种rename要分清Linux和macOS下的情况比Windows更复杂因为“区分大小写”本身就是Linux的特性。Linux下如果文件名是README.md而代码引用了readme.md编译或启动直接报错这就是最常见的需要改名小写的场景。Linux上存在两种rename命令很多人分不清util-linux版本语法是rename 原字符串 新字符串 文件名只能做简单替换。Perl版本语法是rename 规则表达式 文件名支持正则功能强大。Debian/Ubuntu系列默认用的是Perl版本查看版本信息的时候会看到Perl相关提示。如果你不确定可以先运行rename --version 2/dev/null | head -n 1如果显示perl相关字样就是Perl版本。使用时用这一条rename y/A-Z/a-z/ *这里的y/A-Z/a-z/是Perl的tr运算符把文件名里的所有大写字母替换成小写。该命令会处理当前目录下所有文件和子目录里的文件名而且只转文件名不递归进入目录内部。如果也要递归子目录需要使用find配合find . -type f -depth -exec rename y/A-Z/a-z/ {} -depth参数很关键它让find先处理最深层的文件再处理目录本身避免因为目录名变小写后路径发生变化导致找不到文件。4.2 用shell循环处理没有Perl rename的环境macOS默认没有Perl版rename很多精简Linux系统也没有。这时直接用shell循环更稳妥不需要额外装包for f in *; do [ -f $f ] || continue lower$(printf %s $f | tr A-Z a-z) if [ $f ! $lower ]; then echo mv -- \$f\ \$lower\ fi done这条命令先打印出将要执行的改名操作注意我故意用的是echo而不是mv这是干跑预览确认无误后把echo去掉换成真正的mv -- $f $lowerfor f in *; do [ -f $f ] || continue lower$(printf %s $f | tr A-Z a-z) if [ $f ! $lower ]; then mv -- $f $lower fi done要递归处理子目录的话把for f in *换成find . -type f -exec bash -c ... sh {} find . -type f -depth -exec bash -c for f do dir$(dirname -- $f) base$(basename -- $f) lower$(printf %s $base | tr A-Z a-z) if [ $base ! $lower ]; then mv -- $f $dir/$lower fi done sh {} 这段代码相对复杂但好处是不改变目录结构只改文件名。这里的dirname和basename是用来拆路径和文件名避免把目录名也处理了。4.3 处理中文、空格和特殊字符很多人的文件名既有大写字母又有中文比如客户合同.PDF。tr A-Z a-z只处理ASCII范围内的大写字母对中文完全无影响所以客户合同.PDF会变成客户合同.pdf中文保持原样。这是Linux环境比Windows批处理更省心的一个地方。文件里有空格也更常见。上面所有命令我都加了双引号包裹变量空格会被当成文件名的一部分而不会拆词。文件如果以-开头必须用mv --这里的--告诉命令后面是正式文件不是选项。5. 方法四图形化工具懒人和批量场景首选5.1 用Bulk Rename Utility批量转换小写如果你不想碰命令行图形化工具最适合你。Windows上我推荐Bulk Rename Utility简称BRU免费、老牌、规则丰富。操作流程打开BRU进入目标文件夹。用CtrlA全选要处理的文件。在界面上找到“Case”选项卡选择“Lowercase”。下方预览列表会实时显示改名后的文件名确认无误后点击“Rename”按钮。BRU最大的优势是强大且可见你能看到所有规则的叠加效果。它不仅能改大小写还能批量加前缀、去掉括号、替换文字、按规则重新排序。很多朋友问我“批量修改文件名前缀”“批量去除文件名里的括号”用什么工具BRU的“Replace”和“Add”功能可以一次搞定。5.2 ReNamer的规则化方案ReNamer是另一个跨平台改名工具Windows/macOS/Linux都可以用适合需要把改名规则保存下来反复使用的人。它的核心玩法是“规则流”添加规则、调整顺序、预览效果。要把文件名变小写步骤如下把文件或文件夹拖进ReNamer窗口。点击“添加规则”选择“Case”类型。在右侧选择“Lowercase”可以勾选“只应用于文件名”或“扩展名”。预览无误后点击“执行”或导出为批处理文件。ReNamer的好处是它可以同时处理多个规则比如先改小写再加前缀2024_再接重名检测。我之前帮人整理一批企业下载的文件就是用这个工具一次完成“转小写加前缀”。5.3 补充用Excel VBA维护改名清单还有一种被低估的做法是用Excel VBA。这份需求很适合那些喜欢把文件清单放在表格里管理的人。按AltF11打开VBA编辑器插入模块粘贴下面代码Sub BatchLowercase() Dim fso As Object Dim folder As Object Dim file As Object Dim fPath As String fPath D:\test\ 改成你要处理的文件夹路径 Set fso CreateObject(Scripting.FileSystemObject) Set folder fso.GetFolder(fPath) For Each file In folder.Files If StrComp(file.Name, LCase(file.Name), vbBinaryCompare) 0 Then file.Name LCase(file.Name) End If Next MsgBox 处理完成 End Sub这段代码用FileSystemObject遍历指定目录下的文件LCase函数把文件名转成小写StrComp区分大小写比较。它会把文件名和扩展名一起转小写遇到重名会弹错。我通常会在这个基础上加一个Excel工作表先把旧文件名和新文件名两列列出来人工审核一遍再执行。这样虽然比图形工具多几个步骤但适合需要留底单的正式场景。6. 常见问题与实战避坑6.1 重名冲突怎么办改名最怕遇到重名。Windows下如果文件夹里同时存在A.txt和a.txt理论上不能共存的。但注意如果只是把A.txt改成a.txt而原目录里没有a.txtWindows是允许的因为NTFS虽然保留大小写但默认不区分大小写。如果原目录已经有一个a.txtren会直接报“文件已存在”。Linux下更危险如果目标目录里存在目标文件名mv会默认覆盖目标文件导致数据丢失。所以在Linux上执行前一定要先检查冲突。我习惯在干跑命令里加一个判断[ -e $lower ] echo 冲突: $lower这样能在预览阶段把所有会覆盖的情况提前暴露出来。6.2 只改主名不改扩展名有些场景要求扩展名保持大写比如某些老旧系统对扩展名大小写有特殊判断虽然不推荐。这种情况在PowerShell里很好处理用$_.BaseName拿主名用$_.Extension拿扩展名然后把两者拼接回来。在BAT脚本里可以用%~ni拿主文件名、%~xi拿扩展名先对主名做大小写替换再拼接。不过说实话BAT里这么写代码可读性会变差我宁愿用PowerShell。6.3 递归处理和隐藏文件BAT脚本里我写的是dir /b /a-d默认包含隐藏文件吗实际上dir /b不带/a时不会显示隐藏文件我特意加了/a-d只排除目录但不排除隐藏文件所以隐藏文件也可能被处理。PowerShell里如果也要处理隐藏文件需要给Get-ChildItem加-Force参数。Linux下处理隐藏文件要注意shell的通配符*默认不匹配以点号开头的隐藏文件。如果需要可以用find . -type f -name .*或者for f in * .[!.]*这种方式。6.4 中文乱码问题这是被问得最多的一个坑尤其是BAT脚本。BAT脚本保存时必须选ANSI编码。如果你用VS Code另存为UTF-8CMD读取时就会歪掉ren找不到原始文件。最简单的方法是用Windows自带的记事本另存为时编码选ANSI。PowerShellWindows PowerShell 5.1在中文系统下读取文件名没问题但如果你在Windows Terminal里执行一定要确保当前代码页是chcp 65001否则输出预览会乱码。Linux/macOS一般不会乱码但如果终端locale没有设置为UTF-8tr和mv仍然可能显示异常。先跑一句locale看看如果出现LANGC建议改成export LANGen_US.UTF-8再执行。6.5 文件被占用、权限不足批量改名时如果文件正在被Word、Excel、图片查看器打开系统会提示无法重命名。处理前最好把所有相关程序关掉。如果文件有只读属性右键属性里去掉只读或者用命令attrib -r *仅当前目录清理。公司电脑权限受限时需要右键脚本或者PowerShell窗口选择“以管理员身份运行”。7. 一点个人经验我用了很长时间的PowerShell替换方式之后现在的习惯是执行前永远加-WhatIf或先打印mv命令尤其是Linux环境。曾经有一次我复制了一个大文件夹结果源文件里已经有个readme.md我又要改README.md直接mv的话就真的把旧文件覆盖了后悔都来不及。另外建议分批次处理不要一次性扔进去几千个文件。先处理一个小目录确认规则符合预期再扩大到完整目录。如果你未来还要反复执行这种改名任务可以考虑把PowerShell命令保存成一个.ps1脚本并在开头加日志和错误捕获这样数据的可追溯性会好很多。文件名的规范化看起来是小工程但在协作和部署里往往能省掉不少大麻烦这4个方法按你的使用场景挑一个就好。