Sorry, the for statement got broken up...
@echo off
type nul>file.tmp
for /f "delims=" %%i in (file.txt) do (echo %%i>>file.tmp) & if %%i==test1 echo test1-1>>file.tmp
del file.txt
ren file.tmp file.txt
Main Topics
Browse All TopicsHi,
I have a file called file.txt with the following:
test1
test2
I need to add a line "test1-1" between test1 and test2, using a batch file. It should look like:
test1
test1-1
test2
Please help.
Thanx.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
This should let you add as many lines as you want after a given line. Note that any method you use to set the target line you are searching for in file MUST be settled before you start the "FOR" loop. Also, this is XP/2000 version, 9X/ME do not know the "/f" option in the "FOR" command.
Enjoy,
2K
(\o/)
::setup target
set TargetLine="test1"
:: optional - remove :: in next line to get target from command line if given
:: if NOT "%~1"=="" set TargetLine="%~1"
:: write new file looking for target
for /f "delims=" %%K in ( file.txt ) do (
>>filenew.txt echo.%%K
if "%%K"==%TargetLine% CALL :addlines
)
:: cleanup to replace file
if exist file.txt if exist file.backup del file.backup
if exist file.txt if exist filenew.txt ren file.txt file.backup
if exist filenew.txt ren filenew.txt file.txt
:: done - skip to end to avoide running addlines after done.
goto :EOF
:addlines
:: you can add as many lines as you like here, and test2 follows after them
>>filenew.txt echo test1-1
goto :EOF
echo %%i>>file.tmp on the line that ends with the number 2 will echo the line to the screen with errors ( nothing) going to file.tmp
Also, the & is parsed as belonging to the FOR loop so it may not do what it needs until after the loop finished with the file, I haven't checked. If it does that, try ^& and change
echo %%i>>file.tmp
to
>>file.tmp echo %%i
and that shorter program might be quite nifty.
Good Luck,
2K
(\o/)
Here's batch file that uses a technique from Billious to process and keep the blank lines in a file:
@echo off
set _t1=Y
if exist _temp2.dat del _temp2.dat > NUL
find /N /V "" file.txt > _temp1.dat
for /f "delims=" %%f in (_temp1.dat) do call :PROCESS %%f
del _temp1.dat>NUL
echo _temp2.dat has results of conversion
set _t=
goto EXIT
:PROCESS
set _t=%~1
if "%_t1%"=="" goto LOOP
set _t1=
goto EXIT
:LOOP
if "%_t:~0,1%"=="]" goto TESTIT
set _t=%_t:~1%
goto LOOP
:TESTIT
set _t=%_t:~1%
if "%_t%"=="" goto EMPTYLINE
echo %_t%>>_temp2.dat
if %_t%==test1 echo test1-1>>_temp2.dat
goto EXIT
:EMPTYLINE
echo.>>_temp2.dat
goto EXIT
:EXIT
Good Luck,
Steve
<<<
echo %_t%>>_temp2.dat
>>>
This could fail.
With all due respect to Billious, Steve, Seth, Microsoft examples - (I take that back - MS does this too, but with all the resources at their disposal they have no excuse) - and everyone else who codes this way - it's less than 100% accurate, and the example files given in this question fall squarely in the set of data that could cause this line to fail.
At some point in future changes to the data, the user might add lines:
new test line 1
new test line 2
Then at some time in the :PROCESS %_t% will be "new test line 1"
So the parser will build the expanded line as
echo new test line 1>>_temp2.dat
Now it's time to set up the redirect - according to this line, stdout (channel 1) is to go to a file. The data to send is:
new test line
That line of output is changed, but not because the program wanted it. It simply does not realize the parser setup redirection on that line as it was directed, instead of assuming which channel to redirect as it needed to on other lines.
Also at some time in the :PROCESS %_t% will be "new test line 2"
So the parser will build the expanded line as
echo new test line 2>>_temp2.dat
Now it's time to set up the redirect - according to this line, stderr (channel 2) is to go to a file. If this is running in a visible window, the user will see
new test line
and the errors of that echo (there are no errors here) will go to the file. That line of output is effectively deleted, although all of the logic above does NOT indicate it should be. Well, the program does not think it was deleted, but it simply does not realize the parser redirected that line differently than the rest.
This line has no such side-effects, since any possible number at the end of lines cannot be accidentally mistaken for part of the redirect directive.
>>_temp2.dat echo %_t%
Hope this helps,
2K
(\o/)
Oh, my aching head, I'm so confused.
This was a real problem I prooved on an Old box years ago (95 or DOS 6). Since then I've prooved on NT/2000/XP that trailing spaces followed by redirects still cause problems as before. That's only if trailing spaces matter to the data, and because old timers used to add space to prevent this parser problem.
I just now checked and see you are correct, on both NT and 2K the parser has corrected this by changing ">>filename.ext" to " 1>>filename.ext" and the interpreter correctly restrips that last added space from the output. 9X/ME? I don't know but is moot to this question since they don't do "FOR /f" anyway. Lines typed with a single digit hard coded and separated by white space are the only ones that still affect redirection.
So Steve's code is solid and also preserves empty lines which none of our other stuff did.
Two retractions in one day, I think I'll quit while I'm behind.
Thanks Seth for keeping me straight and teaching me something.
2K
(\o/)
Nice addition. The data file is too short to notice the difference in speed, but this might be a bit faster:
:: if string exists stop processing
>nul findstr /b /e "test1-1" file.txt && echo eof
We could also add a flag and check in :addlines to delay the new addition until the line after the target is seen not to be "test1-1" avoid reading the file twice. Caching makes that almost pointless, and that also would create a possible un-needed temp file on every logon, actually taking longer than two file reads.
Enjoy,
2K
(\o/)
Business Accounts
Answer for Membership
by: SethHoytPosted on 2003-11-04 at 15:33:25ID: 9683097
This should do what you want:
@echo off
type nul>file.tmp
for /f "delims=" %%i in (file.txt) do (echo %%i>>file.tmp) & if %%i==test1 echo test1-1
>>file.tmp
del file.txt
ren file.tmp file.txt
-Seth