[在CMD中使用enabledelayedexpansion时如何获取带有特殊字符的子字符串?

问题描述 投票:2回答:1

我想使用cmd重命名一个或多个文件。但其中许多文件都有特殊字符。例如:

DCIM_!01.jpeg
DCIM_&01.jpeg
DCIM_=01.jpeg

通常,我们可以使用此值“ ^”将特殊字符串设置为简单文本。但是当设置了enabledelayedexpansion时,字符串不可设置

set /p mystring=!

用户定义字符串值:!,&,=和其他...

文件名由其他变量“ FOR”定义以在文件夹中搜索它

所以字符串“ File”的值为“ DCIM_!01.jpeg”

更改文件名的命令:

setlocal enabledelayedexpansion
set new_filename=!file:^%mystring%=0!
echo !new_filename!

提示的结果是:

:=0
file:=0
DCIM_!01.jpeg
DCIM_01.jpeg

我要重写“!”设为“ 0”:

DCIM_001.jpeg

当我不使用特殊字符串时,该命令对我有用

string batch-file cmd command prompt
1个回答
1
投票

这里是一个快速的演示代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "TempDir=%TEMP%\%~n0"
if exist "%TempDir%\" goto CreateFiles
md "%TempDir%" && goto CreateFiles
echo Failed to create temporary directory:
echo/
echo "%TempDir%"
echo/
pause
rem The command endlocal is executed implicit by cmd.
exit /B

:CreateFiles
pushd "%TempDir%"
echo DCIM_!01.jpeg>"%TempDir%\DCIM_!01.jpeg"
echo DCIM_^&02.jpeg>"%TempDir%\DCIM_&02.jpeg"
echo DCIM_=03.jpeg>"%TempDir%\DCIM_=03.jpeg"
echo DCIM_%%04.jpeg>"%TempDir%\DCIM_%%04.jpeg"
echo DCIM_)05.jpeg>"%TempDir%\DCIM_)05.jpeg"

:UserPrompt
set "MyString="
set /P "SearchString=String to replace: "
rem Has the user not entered a string?
if not defined SearchString goto UserPrompt
rem Remove all double quotes.
set "SearchString=%SearchString:"=%"
rem Is there no search string left?
if not defined SearchString goto UserPrompt
rem Replace all exclamation marks by vertical bars.
set "SearchString=%SearchString:!=|%"
echo/

for /F "eol=| delims=" %%I in ('dir "*.jpeg" /A-D /B 2^>nul') do (
    set "RealName=%%I"
    set "FileName=%%I"
    rem Replace in file name all exclamation marks by vertical bars.
    call set "FileName=%%FileName:!=|%%"
    setlocal EnableDelayedExpansion
    set "NewName=!FileName:%SearchString%=0!"
    if not "!NewName!" == "!FileName!" echo ren "!RealName!" "!NewName!"
    endlocal
)

echo/
%SystemRoot%\System32\choice.exe /C NY /N /M "Run once more (Y/N):"
if errorlevel 2 goto UserPrompt

popd
rd /Q /S "%TempDir%"
endlocal

您会看到演示代码不适用于包含=的搜索字符串。必须有用于替换等号的特殊代码,或者使用其他脚本解释器(如PowerShell)。另请参阅:How to replace “=” (equal signs) and a string variable?

感叹号的解决方案是在搜索字符串中分别将每个!替换为|,并对当前文件名执行相同的操作,然后再启用延迟的环境变量扩展。文件名不能包含Microsoft有关Naming Files, Paths, and Namespaces的文章中所述的竖线。因此,在启用启用的!进行字符串替换之前,可以安全地用文件名中的|替换所有delayed expansion

[FOR循环中的[!|替换]必须通过用FileName引用环境变量%%来完成。原因是命令行

call set "FileName=%%FileName:!=|%%"
在执行命令

FOR

至]之前由cmd.exe处理>call set "FileName=%FileName:!=|%"
命令

CALL

用于在循环的每次迭代中通过cmd.exe强制对该命令行进行第二次解析和处理,以真正对分配给环境变量FileName的当前字符串值进行字符替换。
另请参见:

。阅读this answer,以获取有关命令

SETLOCAL

ENDLOCAL的详细信息。该演示代码并没有真正运行命令[[REN,它只是输出在删除命令ECHO时将如何执行

REN

© www.soinside.com 2019 - 2024. All rights reserved.