简体   繁体   中英

Running a bat command after find and replace script

I'm using the below script to find and replace a text in XML

setlocal

call :FindReplace "#fromconfig#" "oldtest" new-text

:FindReplace <findstr> <replstr> <file>
set tmp="%temp%\tmp.xml"
If not exist %temp%\_.vbs call :MakeReplace
for /f "tokens=*" %%a in ('dir "%3" /s /b /a-d /on') do (
  for /f "usebackq" %%b in (`Findstr /mic:"%~1" "%%a"`) do (
    echo(&Echo Replacing "%~1" with "%~2" in file %%~nxa
    <%%a cscript //nologo %temp%\_.vbs "%~1" "%~2">%tmp%
    if exist %tmp% move /Y %tmp% "%%~dpnxa">nul

  )
)

del %temp%\_.vbs

: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

I also have a few commands to run after this part, but the batch file exits after executing the above part.

Can you suggest me any way to make the script continue after the above part?

The batch code copied obviously together from other sources without really understanding the code has many small mistakes. The fixed code below works for a file with name 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 is a strange name for a file or file name pattern. I suppose the code should run on a *.xml file and therefore the name of this XML file should be used instead of new-text .

The batch code in question miss all goto :EOF or exit /B (are identical) to exit the current subroutine or the entire batch file. I added command exit /B to exit processing of batch file and goto :EOF to exit each subroutine.

TMP is a predefined environment variable like TEMP which contains the path to folder for temporary files. Therefore value of environment variable TMP should not be overwritten by something different as this could result in unexpected behavior if one of the used console applications or commands depends on TMP expecting that it contains the path to folder for temporary files. The batch code above uses instead the environment variable TempXmlFile . Run in a command prompt window the command set to get displayed the predefined environment variables with their current values.

The folder for temporary files usually contains spaces. Each file/folder name without or with path containing a space or one of these characters &()[]{}^=;!'+,`~ must be enclosed in double quotes to be interpreted correct. Therefore every file/folder path with a reference to environment variable TEMP or TMP must be enclosed in double quotes to be correct interpreted.

The third parameter string passed to subroutine FindReplace is the name of the file to modify or the file name pattern which must be enclosed in double quotes if it contains a space or another special character. Therefore it is not good to use "%3" on command DIR as a file name already enclosed in double quotes results in two double quotes around the file name. Much better is therefore "%~3" because %~3 is replaced on execution by third parameter string without surrounding double quotes.

2^>nul is a redirection for error messages printed to handle STDERR to the device NUL to suppress them with escaping the redirection operator > with ^ to be applied on running command DIR and not being interpreted on FOR command line. This added redirection suppresses the error message output by command DIR if it could not find any file according to third parameter string.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • cscript /?
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • exit /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?

And see also the Microsoft article Using command redirection operators .

Other solutions for replacing text in a file using Windows command line can be found at:
How can you find and replace text in a file using the Windows command-line environment?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM