Reputation: 1971
I am trying to create a simple batch file that will replace a line in a text file with a different line, but keep every other line in the file the same. I found a script somewhere on the internet which I modified slightly and came up with the following code. However, for some reason this code is not echoing any lines ending in "=0" to the new text file as it should be, and is instead echoing them to screen (even with echo off). Does anyone have any suggestions?
Thanks much.
@echo off
if exist prod.ini del new_prod.ini
for /f "tokens=*" %%a in (prod.ini) do call :AddText "%%a"
del prod.ini
rename new_prod.ini prod.ini
exit /b
:AddText %1
@echo on
echo %1
@echo off
set Text=%~1%
if "%Text%"=="server=server-2.domain.com" (
echo server=server-3.domain.com>> new_prod.ini
) else (
echo %~1%>> new_prod.ini
)
exit /b
The original file has some lines like those that follow, but the new file after the script has left out these lines. The script works exactly as expected on the replace, as well as on 20 or so other lines. Only the lines that look as follows cause problems.
_sflag=0
debug_lvl=0
sel_test_lvl=0
ipc_error_logging_lvl=0
ipc_client_debug_lvl=0
ipc_server_debug_lvl=0
Thanks again.
edit: This will be run on hundreds of computers in the organization and using 3rd party tools is not really an option, as installing another application on all machines (even though theoretically possible with the remote management software we will use) is not desired.
Thanks.
Upvotes: 0
Views: 4647
Reputation: 130809
The problem with the original script is this line
echo.%~1>> new_prod.ini
Here is what the line looks like after one of the problem lines is expanded
echo._sflag=0>> new_prod.ini
0>> new_prod.ini
will redirect standard intput to new_prod.ini instead of redirecting standard output because 0 is the symbol for standard input. Not what you wanted of course. Note that standard output is 1 and standard error is 2. >>file
is the same as 1>>file
.
This problem with the original code is easily fixed by putting the redirection at the beginning of the line.
>>new_prod.ini echo.%~1
There are other potential issues with the original code. Using Windows batch to process files is indeed cumbersome and slow. 3rd party tools are preferred if you have access to them.
Sometimes a pure batch solution is needed or wanted anyway.
For a robust case insensitive search and replace, see https://stackoverflow.com/a/8591185/1012053
For a robust case sensitive search and replace, see http://www.dostips.com/forum/viewtopic.php?f=3&t=2710
Upvotes: 1
Reputation: 79155
Your %~1%
needn't the final %
.
@echo off
if exist prod.ini del new_prod.ini
for /f "tokens=*" %%a in (prod.ini) do call :AddText "%%a"
del prod.ini
rename new_prod.ini prod.ini
exit /b
:AddText
@echo on
echo.%1
@echo off
set Text=%~1
if "%Text%"=="server=server-2.domain.com" (
echo.server=server-3.domain.com>> new_prod.ini
) else (
echo.%~1>> new_prod.ini
)
exit /b
Upvotes: 0
Reputation: 16121
Instead of trying to search and replace using script commands, how about using a command line tool to do the same thing? It's easier and faster (and works), and you can script it too. Google has a ton of them, for example, SSR.
Upvotes: 2