Windows 用批处理替换多个文件的字符串
我正在尝试使用建议的脚本 我的目标是能够为多个文件重用脚本。 我有一个文件包含这个脚本,另一个文件只是用不同的参数多次触发脚本 ReplaceString.batWindows 用批处理替换多个文件的字符串,windows,batch-file,cmd,Windows,Batch File,Cmd,我正在尝试使用建议的脚本 我的目标是能够为多个文件重用脚本。 我有一个文件包含这个脚本,另一个文件只是用不同的参数多次触发脚本 ReplaceString.bat @echo off REM -- Prepare the Command Processor -- SETLOCAL ENABLEEXTENSIONS SETLOCAL DISABLEDELAYEDEXPANSION ::BatchSubstitude - parses a File line by line and replace
@echo off
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL DISABLEDELAYEDEXPANSION
::BatchSubstitude - parses a File line by line and replaces a substring"
::syntax: BatchSubstitude.bat OldStr NewStr File
:: OldStr [in] - string to be replaced
:: NewStr [in] - string to replace with
:: File [in] - file to be parsed
:$changed 20100115
:$source http://www.dostips.com
if "%~1"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %3|find /n /v """') do (
set "line=%%B"
if defined line (
call set "line=echo.%%line:%~1=%~2%%"
for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
) ELSE echo.
)
set oldString=foo
set newString=newFoo
ReplaceString.bat %oldString% %newString% someFile.txt >someFile.txt
ReplaceString.bat %oldString% %newString% someFile2.txt >someFile2.txt
让我们说:
foo.bat
@echo off
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL DISABLEDELAYEDEXPANSION
::BatchSubstitude - parses a File line by line and replaces a substring"
::syntax: BatchSubstitude.bat OldStr NewStr File
:: OldStr [in] - string to be replaced
:: NewStr [in] - string to replace with
:: File [in] - file to be parsed
:$changed 20100115
:$source http://www.dostips.com
if "%~1"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %3|find /n /v """') do (
set "line=%%B"
if defined line (
call set "line=echo.%%line:%~1=%~2%%"
for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
) ELSE echo.
)
set oldString=foo
set newString=newFoo
ReplaceString.bat %oldString% %newString% someFile.txt >someFile.txt
ReplaceString.bat %oldString% %newString% someFile2.txt >someFile2.txt
但无论出于何种原因,在成功运行第一个调用后,执行将停止
我试图用START
&call
调用ReplaceString.bat
,试图不将输出重定向到文件,但每次都得到相同的结果
我希望能够强制foo.bat
继续运行,或者ReplaceString.bat
不退出
编辑:
我错误地认为脚本提前结束了,但实际发生的是,我没有接收到控制台的输出,命令是使用CALL
command运行的。
我的脚本的另一个问题是将输出重定向回输入文件,这是通过将输出重定向到临时文件并在调用结束后将其替换为原始文件来解决的 即
ReplaceString.bat
起作用,但您在foo.bat
中以有问题的方式使用它;您应按以下方式进行更改:
set oldString=foo
set newString=newFoo
CALL ReplaceString.bat %oldString% %newString% someFile.txt >someFileX.txt
CALL ReplaceString.bat %oldString% %newString% someFile2.txt >someFile2X.txt
该
调用
命令将启动新的批处理文件上下文以及任何指定参数。什么时候结束
到达第二个批处理文件的第二个批处理文件(或者如果使用了EXIT
),则控制
将在初始CALL
语句之后返回到
参数可以作为简单字符串或使用变量传递
ReplaceString.bat
输出重定向到与在ReplaceString.bat%oldString%%newString%someFile.txt>someFile.txt
中解析的文件相同的文件,则将首先清空输出文件,以便调用的脚本无需解析(或解析空文件)…使用不同的输入和输出文件,如上面的代码示例所示无论您在
foo.bat
中以有问题的方式使用ReplaceString.bat,该ReplaceString.bat
都是有效的;您应按以下方式进行更改:
set oldString=foo
set newString=newFoo
CALL ReplaceString.bat %oldString% %newString% someFile.txt >someFileX.txt
CALL ReplaceString.bat %oldString% %newString% someFile2.txt >someFile2X.txt
请注意,调用从一个批处理程序调用另一个批处理程序:
调用第二个批处理文件
该调用
命令将启动新的批处理文件上下文以及任何指定参数。什么时候结束
到达第二个批处理文件的第二个批处理文件(或者如果使用了EXIT
),则控制
将返回到初始CALL
语句之后
参数可以作为简单字符串或使用变量传递
请注意,如果将ReplaceString.bat
输出重定向到与在ReplaceString.bat%oldString%%newString%someFile.txt>someFile.txt
中解析的文件相同的文件,则将首先清空输出文件,以便调用的脚本无需解析(或解析空文件)…使用不同的输入和输出文件,如上面的代码示例所示
首先,我建议将ReplaceString.bat更改为:
@echo off
rem -- Prepare the Command Processor --
setlocal EnableExtensions DisableDelayedExpansion
::BatchSubstitude - parses a File line by line and replaces a substring"
::syntax: BatchSubstitude.bat OldStr NewStr File
:: OldStr [in] - string to be replaced
:: NewStr [in] - string to replace with
:: File [in] - file to be parsed
:$changed 20100115
:$source http://www.dostips.com
if "%~1"=="" %SystemRoot%\System32\findstr.exe "^::" "%~f0" & goto :EOF
for /f "tokens=1,* delims=]" %%A in ('"type %3|%SystemRoot%\System32\find.exe /n /v """') do (
set "line=%%B"
if defined line (
call set "line=echo.%%line:%~1=%~2%%"
for /f "delims=" %%X in ('"echo."%%line%%""') do %%~X
) else echo.
)
endlocal
每次使用setlocal都会创建整个环境表的副本,将指针推送到堆栈上的上一个环境表,推送到堆栈上命令扩展的当前状态和延迟扩展的当前状态,并推送到堆栈上的当前目录路径。只需一个setlocal就可以启用命令扩展(默认启用)和禁用延迟扩展(默认禁用)
Windows command processor在到达批处理文件处理的退出点时将环境恢复为启动批处理文件时的状态。但是,对每个setlocal命令使用相应的endlocal是一个好主意
使用完整路径和文件扩展名调用findstr和find也很好,因为在环境变量path中,在%SystemRoot%\System32
之前包含一个文件夹路径,其中还包含从Unix移植的find.exe
或findstr.exe
到Windows,但当然工作方式不同,或者是一个find.bat
,或者一个findstr
,其文件扩展名在环境变量PATHEXT中定义
但在处理foo.bat时从未调用带ReplaceString.bat
的第二行的主要原因是:
带有ReplaceString.bat
的第一行没有命令call
因此,foo.bat的处理继续进行ReplaceString.bat,不再返回foo.bat作为非调用另一批处理文件
foo.bat需要以下行:
set oldString=foo
set newString=newFoo
call ReplaceString.bat %oldString% %newString% someFile.txt >someFile_1.txt
move /Y someFile_1.txt someFile.txt
call ReplaceString.bat %oldString% %newString% someFile2.txt >someFile_2.txt
move /Y someFile_2.txt someFile2.txt
有关更多详细信息,请参阅上的我的回答
并且不可能将输出重定向到输入文件。必须将输出重定向到一个单独的文件,然后将该文件移到输入文件上
还有一个注意事项:
ReplaceString.bat适用于许多文件,但并非适用于所有文件内容
例如,在上面运行略为改进的ReplaceString.bat版本
ReplaceString.bat dostips mytips ReplaceString.bat >ReplaceString.txt
导致出现意外的错误消息
系统找不到指定的路径
文件ReplaceString.txt
在第11行按预期将dostips
替换为mytips
,但第12行缺少^
,批处理文件的第13行在ou中完全缺少