在没有真正理解代码的情况下从其他来源明显复制的批处理代码有许多小错误。下面的固定代码适用于名称为 new-text 的文件。
@echo off
setlocal
call :FindReplace "#TargetfromODconfig#" "oldtest" new-text
rem INSERT HERE YOUR OTHER CODE.
endlocal
exit /B
rem The command above exits processing of this batch file to
rem avoid an unwanted fall through to the subroutine below.
rem Subroutine FindReplace searches for all occurrences of the string passed
rem as first parameter to this subroutine in all files matching the file name
rem or file name pattern passed as third parameter in current directory or
rem any subdirectory and replaces all found strings in all found files with
rem the string passed as second parameter.
:FindReplace <findstr> <replstr> <file>
set "TempXmlFile=%TEMP%\tmp.xml"
if not exist "%TEMP%\_.vbs" call :MakeReplace
for /F "tokens=*" %%a in ('dir "%~3" /A-D /B /ON /S 2^>nul') do (
for /F "usebackq" %%b in (`%SystemRoot%\System32\Findstr.exe /I /M /C:"%~1" "%%a"`) do (
echo(&Echo Replacing "%~1" with "%~2" in file "%%~nxa"
<"%%a" %SystemRoot%\System32\cscript.exe //nologo "%TEMP%\_.vbs" "%~1" "%~2">"%TempXmlFile%"
if exist "%TempXmlFile%" move /Y "%TempXmlFile%" "%%~fa" >nul
)
)
del "%TEMP%\_.vbs"
goto :EOF
rem The command above exits subroutine FindReplace and batch processing
rem is continued on the line below the line which called this subroutine.
rem Subroutine MakeReplace just creates a small Windows console script.
:MakeReplace
>"%TEMP%\_.vbs" echo with Wscript
>>"%TEMP%\_.vbs" echo set args=.arguments
>>"%TEMP%\_.vbs" echo .StdOut.Write _
>>"%TEMP%\_.vbs" echo Replace(.StdIn.ReadAll,args(0),args(1),1,-1,1)
>>"%TEMP%\_.vbs" echo end with
goto :EOF
rem The command above exits subroutine MakeReplace and batch processing
rem is continued on the line below the line which called this subroutine.
new-text 是文件或文件名模式的奇怪名称。我想代码应该在 *.xml 文件上运行,因此应该使用这个 XML 文件的名称而不是 new-text。
有问题的批处理代码错过了所有goto :EOF 或exit /B(相同)以退出当前子程序或整个批处理文件。我添加了命令exit /B 以退出批处理文件的处理,并添加了goto :EOF 以退出每个子程序。
TMP 是一个预定义的环境变量,例如 TEMP,其中包含临时文件的文件夹路径。因此,环境变量 TMP 的值不应被不同的东西覆盖,因为如果使用的控制台应用程序或命令之一依赖于预期它包含的 TMP,这可能会导致意外行为临时文件的文件夹路径。上面的批处理代码使用环境变量TempXmlFile。在命令提示符窗口中运行命令set 以显示预定义的环境变量及其当前值。
临时文件的文件夹通常包含空格。每个文件/文件夹名称不带或带有包含空格或这些字符之一&()[]{}^=;!'+,`~ 的路径必须用双引号括起来才能正确解释。因此,每个引用环境变量 TEMP 或 TMP 的文件/文件夹路径必须用双引号括起来才能正确解释。
传递给子程序FindReplace 的第三个参数字符串是要修改的文件名或文件名模式,如果它包含空格或其他特殊字符,则必须用双引号括起来。因此,在命令 DIR 上使用"%3" 是不好的,因为文件名已经包含在双引号中,导致文件名周围有两个双引号。因此,"%~3" 更好,因为 %~3 在执行时被第三个参数字符串替换,不带双引号。
2^>nul 是将打印的错误消息重定向到处理 STDERR 到设备 NUL 以通过转义 redirection operator > 和 ^ 来抑制它们应用于运行命令 DIR 而不会在 FOR 命令行上解释。如果根据第三个参数字符串找不到任何文件,则此添加的重定向会抑制命令 DIR 输出的错误消息。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?
cscript /?
del /?
dir /?
echo /?
endlocal /?
exit /?
findstr /?
for /?
goto /?
if /?
move /?
rem /?
set /?
setlocal /?
另请参阅 Microsoft 文章 Using command redirection operators。
使用 Windows 命令行替换文件中的文本的其他解决方案可以在以下位置找到:
How can you find and replace text in a file using the Windows command-line environment?