从网上下载到的某些资源(感谢那些无私奉献学习资源的人),文件名或目录名有一些特殊字符,如何批量移除呢?
本文介绍利用批处理脚本,遍历指定目录以及指定目录下的所有子目录批量移除文件名和目录名中特殊字符的方法。方便快捷绿色省心~~

遍历当前目录以及所有子目录批量处理

批处理脚本内容

创建一个后缀为 .bat.cmd 的批处理文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@echo off
setlocal enabledelayedexpansion
chcp 65001

:: 如果要指定绝对路径,用以下两行,注释 set path=. 所在行。也就是用以下两行代替 set path=. 这一行。
:: set path="C:\temp\test"
:: cd "/d %path%"

set path=.
:: echo.&set /p path=please input path:

:: 删除特殊字符,记得替换成你自己需要删除的
set adv=【我是特殊字符】
:: echo.&set /p adv=please input to be delete characters:

call:renameFiles

for /f "delims=" %%i in ('dir /ad/b/s "%path%"') do (
cd %%i
call:renameFiles
)

echo.
echo 处理完毕
echo.

pause

:: 子过程一般放在最后,主程序最后要加上exit或跳转语句,避免错误的进入子过程。
:: 如果没有 exit,子程序还会被执行(而不是调用)一次,这样在执行 echo %1 时,因为没有参数,会提示:ECHO is off.
exit

:renameFiles
echo 正在处理的目录:【%cd%】 ...

:: 先删除空格
for /f "delims=" %%i in ('dir /b *.*') do (
set "foo=%%~nxi"
set foo=!foo: =!
ren "%%~fi" "!foo!"
)

for /f "delims=" %%i in ('dir /b *%adv%*') do (
:: echo %%i
set var=%%i
set var=!var:%adv%=!
echo rename "%%i" to "!var!"
ren "%%i" "!var!"
)

echo.
goto:eof

批处理脚本说明

  • 该批处理脚本会把脚本中变量 path 定义的路径下、以及该路径下的所有子目录(含子目录下的子目录)下的文件名和目录名中的 adv 定义的字符删除,还一个干净的文件名和目录名。
  • 如果子目录下的子目录名也包含特殊字符,第一次处理时会提示:The system cannot find the path specified.,这是因为目录名被改了,之前读入内存的目录名不存在了,这没有关系,重复执行该脚本,直到不再出现这个提示为止即表示所有目录名和文件名都已经改完了。
  • path=. 表示当前目录,需要把此批处理文件复制到需要处理的顶层文件夹下再双击执行。
  • 如果设置 path 为绝对路径,则脚本文件放哪个位置都行。
  • 也可以每次输入需要处理的绝对路径和需要移除的特殊字符,见下面 path 和 adv 变量的下一行注释代码。

仅处理当前目录下的文件名和目录名

创建一个后缀为 .bat.cmd 的批处理文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@echo off
:: 仅处理当前目录下的所有文件,所以,需要把该文件 copy 至需要改名的文件夹下,双击执行
setlocal enabledelayedexpansion
chcp 65001

:: 先删除空格
for /f "delims=" %%i in ('dir /b *.*') do (
set "foo=%%~nxi"
set foo=!foo: =!
ren "%%~fi" "!foo!"
)

:: 删除特殊字符,记得替换成你自己需要删除的
set adv=【我是特殊字符】

for /f "delims=" %%i in ('dir /b *%adv%*') do (
::echo %%i
set var=%%i
set var=!var:%adv%=!
echo rename "%%i" to "!var!"
ren "%%i" "!var!"
)

pause

处理过程,以下介绍均为只处理当前目录

特殊字符不带空格

如:test【我是特殊字符】.txt
这类文件用以下脚本即可正常处理,批处理脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off
setlocal enabledelayedexpansion
chcp 65001
set adv=【我是特殊字符】

for /f "delims=" %%i in ('dir /b *%adv%*') do (
::echo %%i
set var=%%i
set var=!var:%adv%=!
echo rename "%%i" to "!var!"
ren "%%i" "!var!"
)

pause

特殊字符包含空格

但是,如果需要删除的特殊字符部分有空格,如:1. test - [加微信 xxxx 有妹子].txt,下面的批处理脚本不能达到去除特殊字符的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off
setlocal enabledelayedexpansion
chcp 65001
set adv="- [加微信 xxxx 有妹子]"

for /f "delims=" %%i in ('dir /b *%adv%*') do (
::echo %%i
set var=%%i
set var=!var:%adv%=!
echo rename "%%i" to "!var!"
ren "%%i" "!var!"
)

pause

执行的时候会提示:

1
2
rename "1. test - [加微信 xxxx 有妹子].txt" to "1. test - [加微信 xxxx 有妹子].txt"
Press any key to continue . . .

解决

在删除特殊字符前,先将空格删除,然后,处理方式就与删除不带空格的特殊字符相同了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@echo off
chcp 65001
setlocal enabledelayedexpansion

:: 先删除空格
for /f "delims=" %%i in ('dir /b *.*') do (
set "foo=%%~nxi"
set foo=!foo: =!
ren "%%~fi" "!foo!"
)

:: 删除特殊字符,记得替换成你自己需要删除的
set adv=-[加微信xxxx有妹子]

for /f "delims=" %%i in ('dir /b *%adv%*') do (
::echo %%i
set var=%%i
set var=!var:%adv%=!
echo rename "%%i" to "!var!"
ren "%%i" "!var!"
)

pause

执行结果:

1
2
rename "1.test-[加微信xxxx有妹子].txt" to "1.test.txt"
Press any key to continue . . .

批量删除文件名中的空格

  • 会处理当前目录以及所有子目录和子目录下的所有文件,如子目录也带空格,则需要多执行几次,因为子目录会先被修改。
  • 正确的姿势是,在循环里判断是否为文件夹,如果是,则先处理文件夹下的文件,最后处理文件夹名,这一点请读者自行研究。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @echo off&setlocal enabledelayedexpansion

    for /f "delims=" %%i in ('dir /s/b *.*') do (
    set "foo=%%~nxi"
    set foo=!foo: =!
    ren "%%~fi" "!foo!"
    )

    pause

百度 PC 端下载文件完成后,文件名后缀没有被及时修改(其实是下载完成了的),用秕处理脚本删除这些后缀

但并不总是这样,后来的版本没有这个问题,估计官方修复这个 bug 了。批量修改脚本如下:

1
2
3
4
@ECHO OFF
FOR /F "delims=" %%I IN ('DIR /A-D /B *.baiduyun.p.downloading.*') DO REN "%%~I" "%%~nI"
FOR /F "delims=" %%I IN ('DIR /A-D /B *.baiduyun.p') DO REN "%%~I" "%%~nI"
FOR /F "delims=" %%I IN ('DIR /A-D /B *.baiduyun') DO REN "%%~I" "%%~nI"

bat批处理的注释语句

  1. :: 注释内容(第一个冒号后也可以跟任何一个非字母数字的字符)
  2. rem 注释内容(不能出现重定向符号和管道符号)
  3. echo 注释内容(不能出现重定向符号和管道符号)
  4. if not exist nul 注释内容(不能出现重定向符号和管道符号)
  5. :注释内容(注释文本不能与已有标签重名)
  6. %注释内容%(可以用作行间注释,不能出现重定向符号和管道符号)
  7. goto 标签 注释内容(可以用作说明goto的条件和执行内容)
  8. :标签 注释内容(可以用作标签下方段的执行内容)

后记,对变量赋值含中文时找不到文件

现象

批处理文件变量赋值语句set adv=【我是特殊字符】,给变量赋值含有中文时,如果 cmd/PowerShell 的编码为非 UTF-8,则不会正常执行。

解决方法一

通过动态赋值的方式,可以正常执行,具体代码如下:

1
echo.&set /p adv=please input to be delete characters:

解决办法二

修改 cmd/PowerShell 的默认编码为 UTF-8。

直接修改注册表

一劳永逸,具体可参考:windows 控制台 cmd/PowerShell 中文显示乱码,解决方法

在脚本最前面指定,更具通用性,本文介绍的脚本已经添加

另一种方式,简单粗暴但是非常实用,就是在脚本前面添加 chcp 65001,每次执行批量删除文件名中的特殊字符之前,先设置编码格式。