该脚本可以将某些字符替换为文件名中的指定字符,但不适用于tilde ~。
以下两个部分工作正常。
@echo off
setlocal enabledelayedexpansion
for %%a in (*_*) do (
set file=%%a
ren "!file!" "!file:_=A!"
)
for %%a in (*-*) do (
set file=%%a
ren "!file!" "!file:-=B!"
)
Run Code Online (Sandbox Code Playgroud)
但是这部分不起作用。
for %%a in (*~*) do (
set file=%%a
ren "!file!" "!file:~=C!"
)
Run Code Online (Sandbox Code Playgroud)
为什么更换~不起作用以及如何解决?
您正在使用子字符串替换语法(例如!file:search=replac!),该语法不允许搜索字符串以开头~,因为那样的话,它将与子字符串扩展语法(例如!file:~pos,len!)混淆。
您可以做的是使用for /F以下~字符分割文件名:
for /F "tokens=1* delims=~ eol=~" %%I in ('dir /B /A:-D "*~*"') do (
if not "%%J" == "" ren "%%I~%%J" "%%IC%%J"
)
Run Code Online (Sandbox Code Playgroud)
仅当存在单个~字符且不在第一个位置时,此方法才起作用。
如果~在任意位置有多个字符,它将变得更加复杂:
@echo off
for /F "delims= eol=|" %%F in ('dir /B /A:-D "*~*" ^| find "~"') do (
set "FILE=%%F" & set "EXT=%%~xF"
call :SUB NAME "%%~nF" C
setlocal EnableDelayedExpansion
ren "!FILE!" "!NAME!!EXT!"
endlocal
)
exit /B
:SUB
set "#RET=%~1"
set "STR=%~2"
set "CHR=%~3"
set "LEFT=" & set "REST="
if not defined STR goto :NEXT
:LOOP
set "REST=%STR:*~=%"
if "%REST%" == "%STR%" goto :NEXT
for /F "delims=~ eol=~" %%E in ("_%STR%") do set "LEFT=%%E"
set "STR=%LEFT:~1%%CHR%%REST%"
goto :LOOP
:NEXT
set "%#RET%=%STR%"
exit /B
Run Code Online (Sandbox Code Playgroud)
该子例程:SUB在每个~循环中拆分文件名字符串,并通过替换~为指定字符来重建它。
需要过滤器| find "~"(以及if not "%%J" == ""第一种方法中的条件),因为dir还要匹配短文件名(通常包含一个~字符)。如果在系统上禁用了此类8.3文件名,则可能会删除这些其他代码部分(尽管它们不会造成损害)。