I was searching for a batch script which edits a specific and known line in another batch-file.
I found this solution (Stackoverflow: Batch - edit specified line in text file) and it was almost workiing properly. The only problem I had with the script from Endoro is that it deletes the colons at the start of a line which I don't want to edit. Is there a way to avoid this from happening?
Help would be much appreciated! Thanks in advance!
#ECHO OFF &SETLOCAL
:Input
set /p version=Please Enter Version:
:Replacement
SET "file=test.bat"
SET /a Line#ToSearch=4
SET "Replacement=set jversion = %Version%_x86"
(FOR /f "tokens=1*delims=: " %%a IN ('findstr /n "^" "%file%"') DO (
SET "Line=%%b"
IF %%a equ %Line#ToSearch% SET "Line=%Replacement%"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO(!Line!
ENDLOCAL
))>"%file%.new"
TYPE "%file%.new"
MOVE "%file%.new" "%file%"
for /F treats subsequent delimiters as one. findstr /N precedes every line with a line number and a colon. So for instance if the third line is :abcd ef, for /F receives 3::abcd ef. After parsing the two tokens, you will get 3 and abcd ef. That is why leading colons disappear.
To overcome this, use sub-string replacement syntax; supposing variable Line contains the entire line including the line number prefix (string 3::abcd ef from above), use SET "Line=!Line:*:=!" to remove everything up to and including the first colon (so the resulting string is :abcd ef).
To get the line number, use another for /F loop with : as delimiter, fetching the first token only.
Here is the fixed script:
#ECHO OFF &SETLOCAL
:Input
set /p version=Please Enter Version:
:Replacement
SET "file=test.bat"
SET /a Line#ToSearch=4
SET "Replacement=set jversion = %Version%_x86"
(FOR /f "delims=" %%a IN ('findstr /n "^" "%file%"') DO (
SET "Line=%%a"
rem // Use a `for /F` loop to extract the line number:
for /F "delims=:" %%N in ("%%a") do set "LNum=%%N"
SETLOCAL ENABLEDELAYEDEXPANSION
rem // Use sub-string replacement to split off
rem // the preceding line number and one colon:
SET "Line=!Line:*:=!"
IF !LNum! equ %Line#ToSearch% SET "Line=%Replacement%"
ECHO(!Line!
ENDLOCAL
))>"%file%.new"
TYPE "%file%.new"
MOVE "%file%.new" "%file%"
Related
I'm trying to extract every value for FileRef from a string I've already extracted out of a file. Unfortunately, the string is one line which makes it more difficult to use for /f "tokens=*".
The string is:
"<Cim:TrnTable_list><Cim:TrnTable Id="Root"><Cim:TrnElem Ref="3" FileRef="A1-FS.elt"/><Cim:TrnElem Ref="4" FileRef="A1-MS.elt"/><Cim:TrnElem Ref="9" FileRef="Product\Product-v1\Product-v1-MD.elt"/><Cim:TrnElem Ref="11" FileRef="Product\Product-v2\Product-v2-MD.elt"/><Cim:TrnElem Ref="12" FileRef="RunnerPart_Assembly#1.elt"/></Cim:TrnTable></Cim:TrnTable_list>"
How to get every value for FileRef inserted into a variable in the following format?:
A1-FS.elt?A1-MS.elt?Product\Product-v1\Product-v1-MD.elt?Product\Product-v2\Product-v2-MD.elt?RunnerPart_Assembly#1.elt
I mean, then I could loop trough them using for /f "delims=?" right?
Or is there a way to convert each ? in the above example to a 'new line' within one string, or maybe even better ideas to loop trough each FileRef-value?
Many thanks!
Squashman is right in his comment, use a language that is capable of handling XML data natively.
Anyway, if you insist on using pure Windows batch scripting, you could assemble a new string with ? symbols as separator like in the following script:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~dpn0.txt" & rem // (path to file containing the line of text)
(set ^"_LF=^
%= empty line =%
^") & rem // (this constitutes a new-line character)
rem // Initialise collection variable:
set "COLL=?"
rem // Read line from file:
for /F "usebackq delims=" %%L in ("%_FILE%") do (
set "LINE=%%~L"
setlocal EnableDelayedExpansion
rem // Replace `><` by `>` + line-break + `<`:
set ^"LINE=!LINE:^>^<=^>^%_LF%%_LF%^<!^"
rem // Read one tag enclosed within `<` and `>`:
for /F "delims=" %%I in ("!LINE!") do (
endlocal
set "ITEM=%%I"
rem // Extract string between ` FileRef` and `/>`:
setlocal EnableDelayedExpansion
set "ITEM=!ITEM:* FileRef=!"
set "ITEM=!ITEM:/>=!"
rem // Check for `=`-sign after `FileRef`:
if "!ITEM:~,1!"=="=" (
rem // Remove leading `=` and surrounding `""`:
for /F "delims=| eol=|" %%F in ("!ITEM:~1!") do (
endlocal
set "NAME=%%~F"
rem // Assemble return string using `?` as separator:
setlocal EnableDelayedExpansion
for /F "delims=| eol=|" %%J in ("!COLL!!NAME!?") do (
endlocal
set "COLL=%%J"
setlocal EnableDelayedExpansion
)
)
)
)
endlocal
)
rem // Return collection variable:
setlocal EnableDelayedExpansion
echo(!COLL:~1,-1!
endlocal
endlocal
exit /B
Toggling delayed expansion is done in order not to have trouble with ! symbols.
Better than collecting all values in a single variable is to just loop through them in my opinion.
This is one other way to brute force this. This code will put each FileRef into its own variable and sequence the variable name up.
#echo off
FOR /F "delims=" %%G IN (line.txt) do set "line=%%G"
set i=0
:loop
set /a i+=1
set "line=%line:*FileRef=%"
FOR /F "tokens=1* delims==/" %%G IN ("%line%") DO (
set "var%i%=%%~G"
set "line=%%H"
)
echo "%line%"|find /I "fileref" >nul 2>&1 &&GOTO loop
set var
pause
When executed it will output this.
C:\BatchFiles\SO\XML>bruteforce.bat
var1=A1-FS.elt
var2=A1-MS.elt
var3=Product\Product-v1\Product-v1-MD.elt
var4=Product\Product-v2\Product-v2-MD.elt
var5=RunnerPart_Assembly#1.elt
Press any key to continue . . .
If you don't want the data assigned into their own individual variables you can just use the %%G meta-variable directly inside the FOR command.
This is my first posting so if the format is not as it supposed to be please excuse me for this. (Suggestions for
improvement are welcome.)
I am trying to create a batchfile that will read last lines from logfiles and copy them to a new file.
Until now I have found here a way to read the last line.
Code would be something like:
for /f %%i in ('find /v /c "" ^< someFile.txt') do set /a lines=%%i
set /a startLine=%lines% - 1
more /e +%startLine% someFile.txt > lastLines.txt
The above code works for one file at a time. What I need is to read the last line from all files in a known list and add this line to a new .csv file.
I have been using the following code for getting the 4th entry in the logfiles but it returns every line of every logfile:
for /f %%x in (%list%) do for /f "delims=.txt, tokens=4" %%i in (%%x.txt) do echo %%x, %%i >> output.csv
What I would need is a sort of combination of both but I don't know how to combine them and make the complete last line be copied to the .csv file.
===
#Magoo:
Thanx for your reaction.
In every logfile can be 1 to >100 lines with comma separated information. Something like:
"LOGON,6-1-2015,12:43:39,USERNAME,HOSTNAME,,,,192.168.209.242,00:21:5A:2E:64:5E"
The last code with the 4th entry was used to get a list of all accounts that had logged in to the computers. This code gave me a very large list of all logon/logoff events on all computerlogs I checked in %list%.
In %list$ I had all the names of logfiles I wanted to be checked. This returned all lines.
For a new batchfile I need only the last logon/logoff entry and I want the whole last line.
So I have a .txt file with the hostnames of all computers I need to examine.
This .txt file will be read line by line via the variable %list%.
From every logfile I need only the last line copied to an output file.
===
I just tried the solution offered by JosefZ. Unfortunately this does not work for me yet. No lastlines are copied to the resultfile. In the code I removed the extra entry for possible lastlines for there are no empty lines in the logs, I also added an entry for the hostname I want to be available in the result. JosefZ had the filename there:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "host=%%~x"
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=.\logs\%filename:&=^&%.txt"
echo %host%,%lastline%>>output.csv
goto :eof
The resultfile shows only the hostnames. I'll puzzle some more with this but all tips are welcome!
===
Got it!!!
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set filename= :: *empty previous filename*
set lastline= :: *empty previous lastline*
set "host=%%~x"
set "filename=.\logs\%host%.txt" :: *creating the filename from path+hostname+extention*
for /F "tokens=*" %%G in ('type "%filename%"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
echo %host%,%lastline%>>output.csv
goto :eof
Your approach with line numbering could fail if a file has more trailing empty lines. Fortunately for /F loop ignores (does not iterate) empty lines; let's put to use this feature: in the script used next practices:
disabledelayedexpansion to allow ! in file names
set "list=_listing.txt" where the _listing.txt contains list of file names (full path and extension .txt including), one file name on one line: got by dir /b /s *.txt>_listing.txt
type nul>files\output.csv to empty the output file (optional)
set "lastline=!!!file empty!!!" to initialize variable %lastline%; could be set "lastline=" as well
call :lline to process variables %filename% and %lastline%
set "filename=%filename:&=^&%" to allow & in file names
The script is as follows:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>files\output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "filename=%%~x"
set "lastline=!!!file empty!!!"
rem the whole line
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
rem the fourth token only
rem for /F "tokens=4" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=%filename:&=^&%"
echo %filename% %lastline%
rem >>files\output.csv
goto :eof
Sample _listing.txt file:
d:\bat\files\1exclam!ation.txt
d:\bat\files\2exc!lam!ation.txt
d:\bat\files\11per%cent.txt
d:\bat\files\12per%cent%.txt
d:\bat\files\17per%Gcent.txt
d:\bat\files\18per%%Gcent.txt
d:\bat\files\21ampers&nd.txt
d:\bat\files\22ampers&&nd.txt
Output:
d:\bat>lastlines
d:\bat\files\1exclam!ation.txt 0 15.01.2015 1:52:28.48 -15072 20465
d:\bat\files\2exc!lam!ation.txt 6 15.01.2015 1:52:28.50 3250 16741
d:\bat\files\11per%cent.txt -8 15.01.2015 1:52:28.50 -3692 27910
d:\bat\files\12per%cent%.txt !!!file empty!!!
d:\bat\files\17per%Gcent.txt 0 15.01.2015 1:52:28.56 14508 12374
d:\bat\files\18per%%Gcent.txt 1 15.01.2015 1:52:28.56 30540 26959
d:\bat\files\21ampers&nd.txt 15.01.2015 1:22:50.18
d:\bat\files\22ampers&&nd.txt 15.01.2015 1:22:50.18
Honestly, all that ballast is for (possibly) trailing empty lines in files and for (possibly) ! and & in file names only; all could be done with
for /f %%x in (%list%) do for /f "skip=%startLine% tokens=4" %%i in (%%x) do echo %%x, %%i >> output.csv
You should use a simple FOR to iterate a list of values, not FOR /F.
Something like the following should work:
#echo off
setlocal enableDelayedExpansion
>>output.csv (
for %%F in (
"file1.log"
"file2.log"
"file3.log"
etc.
) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
The quotes around the file names are there in case you get a name with spaces.
You could use your LIST variable if it looks something like
set LIST="file1.log" "file2.log" "file3.log" etc.
#echo off
setlocal enableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
If any of your file names contain the ! character, then you must toggle delayed expansion ON and OFF within your loop. Otherwise the delayed expansion will corrupt the names when %%F is expanded.
#echo off
setlocal disableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
setlocal enableDelayedExpansion
more +!skip! %%F
endlocal
)
)
I am writing a .bat program that will find and replace text in a file. The problem that I am having is that it is removing blank lines and left justifying the other lines. I need the blank lines to remain and the new text to remain in the same location. Here is what I have wrote, and also the result. Can anybody please help.
program:
#ECHO OFF
cls
cd\
c:
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (samplefile.tx) do (
Set str=%%a
set str=!str:day=night!
set str=!str:winter=summer!
echo !str!>>samplefile2.txt)
ENDLOCAL
cls
exit
samle File:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
day
winter
below is the result:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
night
summer
I need the lines, spaces and new text to remain in the same position while making the text replacement. Please help
Your use of "tokens=* delims= " will trim leading spaces. Instead, use "delims=" to preserve leading spaces.
FOR /F always skips empty lines. The trick is to insert something before each line. Typically FIND or FINDSTR is used to insert the line number at the front of each line.
You can use !var:*:=! to delete the the line number prefix from FINDSTR.
Use echo(!str! to prevent ECHO is off message when line is empty
It is more efficient (faster) to redirect only once.
#echo off
setlocal enableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
)
)
This still has a potential problem. It will corrupt lines that contain ! when %%A is expanded because of the delayed expansion. The trick is to toggle delayed expansion on and off within the loop.
#echo off
setlocal disableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
setlocal enableDelayedExpansion
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
endlocal
)
)
Or you could forget custom batch entirely and get a much simpler and faster solution using my JREPL.BAT utility that performs regular expression search and replace on text. There are options to specify multiple literal search/replace pairs.
jrepl "day winter" "night summer" /t " " /l /i /f sampleFile.txt /o sampleFile2.txt
I used the /I option to make the search case insensitive. But you can drop that option to make it case sensitive if you prefer. That cannot be done easily using pure batch.
#ECHO Off
SETLOCAL
(
FOR /f "tokens=1*delims=]" %%a IN ('find /n /v "" q27459813.txt') DO (
SET "line=%%b"
IF DEFINED line (CALL :subs) ELSE (ECHO()
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof
Thi should work for you. I used a file named q27459813.txt containing your data for my testing.
Produces newfile.txt
Will not work correctly if the datafile lines start ].
Revised to allow leading ]
#ECHO Off
SETLOCAL
(
FOR /f "delims=" %%a IN ('type q27459813.txt^|find /n /v "" ') DO (
SET "line=%%a"
CALL :subs
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:*]=%"
IF NOT DEFINED line ECHO(&GOTO :EOF
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof
I am creating a code that strips through different MAC addresses randomly, but cannot figure out how to do this. My thought on how to approach this is to randomize or rearrange the order of the MAC address in the text file with this script, but I cannot figure out how to do this with a batch file. How this will work is that it will read "maclist.txt", then create a new temp file with the random order "maclist_temp.txt", that will be the rearranged file. Then, it will pull this randomized file in order.
I have tried Google and searching the web, but I haven't found anything too useful. I'm still actively looking, but any advice would be extremely useful.
Something as simple as extracting and deleting a random line and then adding to the bottom might work. Randomization would be better though, but I want to keep the original list. Something like:
Make a temp copy of maclist.txt called maclist_temp.txt
Take one random MAC address, remove it from maclist_temp.txt
Readd it to the bottom
That is all I want, but any suggestions are welcome.
You may try this batch file to help you to shuffle your maclist.txt. The usage of the batch code is
C:\> type list.txt | shuffle.bat > maclist_temp.txt
Here are the contents of shuffle.bat:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET TmpFile=tmp%RANDOM%%RANDOM%.tmp
TYPE NUL >%Tmpfile%
FOR /F "tokens=*" %%i IN ('MORE') DO SET Key=!RANDOM!!RANDOM!!RANDOM!000000000000& ECHO !Key:~0,15!%%i>> %TmpFile%
FOR /F "tokens=*" %%i IN ('TYPE %TmpFile% ^| SORT') DO SET Line=%%i&ECHO.!Line:~15!
::DEL %TmpFile%
ENDLOCAL
After issuing the above command, maclist_temp.txt will contain a randomized list of MAC addresses.
Hope this helps.
Here is a simpler method to randomize/randomise a file, no temp files needed. You can even reuse the same input filename.
Limitations are: blank lines and line starting with ; will be skipped, and lines starting with = will have all leading = signs stripped and ^ characters are doubled.
#echo off
setlocal
for /f "delims=" %%a in (maclist.txt) do call set "$$%%random%%=%%a"
(for /f "tokens=1,* delims==" %%a in ('set $$') do echo(%%b)>newmaclist.txt
endlocal
I really like foxidrive's approach. Nevertheless I want to provide a solution with all the listed limitations eliminated (although cmd-related restrictions like file sizes < 2 GiB and line lengths < ~ 8 KiB remain).
The key is delayed expansion which needs to be toggled to not lose explamation marks. This solves all the potential problems with special characters like ^, &, %, !, (, ), <, >, | and ".
The counter index has been implemented in order not to lose a single line of the original text file, which could happen without, because random may return duplicate values; with index appended, the resulting variable names $$!random!.!index! are unique.
The findstr /N /R "^" command precedes every line of the original file with a line number followed by a colon. So no line appears empty to the for /F loop which would ignore such. The line number also implicitly solves the issue with leading semicolons, the default eol character of for /F.
Finally, everything up to and including the first colon (remember the said prefix added by findstr) is removed from every line before being output, hence no more leading equal-to signs are dismissed.
So here is the code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set /A "index=0"
for /f "delims=" %%a in ('findstr /N /R "^" "%~dpn0.lst"') do (
setlocal EnableDelayedExpansion
for /F %%b in ("$$!random!.!index!") do (
endlocal
set "%%b=%%a"
)
set /A "index+=1"
)
> "%~dpn0.new" (
for /f "delims=" %%a in ('set $$') do (
set "item=%%a"
setlocal EnableDelayedExpansion
echo(!item:*:=!
endlocal
)
)
endlocal
exit /B
This seems to work. Feed it a command line parameter of the file to randomize.
#echo off
setlocal EnableDelayedExpansion
rem read the number of lines in the file
rem the find prepends the line number so we catch blank lines
for /f "delims=" %%n in ('find /c /v "" %1') do set "len=%%n"
set len=!len:*: =!
rem echo %1 has %len% lines
rem Relocate as many lines as there are lines in the file
for /l %%j in (1 1 !len!) do (
rem echo starting round %%j
rem geta random number between 1 and the number of lines in the file
set /a var=!random! %% !len! + 1
rem echo relocating line !var!
rem make sure there is no temp file
if exist %1.temp del %1.temp
rem read each line of the file, write any that don't match and then write the one that does
<%1 (
for /l %%i in (1 1 !len!) do (
rem if it is the target line then save it
if %%i == !var! (
set /p found=
rem echo saving !found!
)
rem if it is the target line then write it
if not %%i == !var! (
set /p other=
rem echo writing !other!
echo !other!>> %1.temp
)
)
rem now write the target line at the end
rem echo appending !found!
echo !found!>> %1.temp
)
rem replace the original with the temp version
move %1.temp %1>nul
)
rem print the result
type %1
Place in cmd file
for /f "tokens=2 delims=/" %%m in ('cmd /e:on /v:on /c "for /f %%f in (maclist.txt) do #echo !random!/%%f" ^| sort') do echo %%m
It spawns a cmd which reads the mac list in the inner for, prefixes a random value and a slash to the mac and sorts the list. Then this list is splitted in the outter for using the slash as delimiter and printing the mac address.
I'd like to print each line of 2 separate txt files alternately using a for loop in a batch file, I tried using an AND but was given: "AND was unexpected at this time" in cmd.exe when I ran my batch. Any ideas?
FOR /F "tokens=*" %%F in (!logPath!) AND for /f "tokens=*" %%H in (%%refLogPath) DO (
REM print each line of log file and refLog file sequentially
echo %%F
echo %%H
REM set logLine=%%F
REM check 'each line' of log file against ENG-REF.log
)
There isn't a keyword like AND, normally you couldn't solve this with two FOR loops.
But there is an alternative way to read a file with set /p.
setlocal EnableDelayedExpansion
<file2.txt (
FOR /F "delims=" %%A in (file1.txt) DO (
set /p lineFromFile2=
echo file1=%%A, file2=!lineFromFile2!
)
)
I believe this is as robust as a batch solution can get.
It handles blank lines in both files
It can read up to approximately 8k bytes on each line
The number of lines in the files does not have to match
A line can begin with any character (avoiding a FOR /F EOL issue)
A line can contain ! without getting corrupted (avoiding a problem of expanding a FOR
variable while delayed expansion is enabled)
Lines can be either Unix or Windows style.
Control characters will not be stripped from end of line
But this solution will get progressively slower as it reads a large file because it must rescan the 2nd file from the beginning for every line.
#echo off
setlocal disableDelayedExpansion
set "file1=file1.txt"
set "file2=file2.txt"
for /f %%N in ('find /c /v "" ^<"%file2%"') do set file2Cnt=%%N
findstr /n "^" "%file1%" >"%file1%.tmp"
findstr /n "^" "%file2%" >"%file2%.tmp"
set "skip=0"
set "skipStr="
for /f "usebackq delims=" %%A in ("%file1%.tmp") do (
set "ln1=%%A"
call :readFile2
set /a "skip+=1"
)
if %file2Cnt% gtr %skip% (
for /f "usebackq skip=%skip% delims=" %%B in ("%file2%.tmp") do (
set "ln2=%%B"
setlocal enableDelayedExpansion
set "ln2=!ln2:*:=!"
(echo()
(echo(!ln2!)
)
)
del "%file1%.tmp" 2>nul
del "%file2%.tmp" 2>nul
exit /b
:readFile2
if %skip% gtr 0 set "skipStr=skip=%skip% "
if %file2Cnt% gtr %skip% (
for /f "usebackq %skipStr%delims=" %%B in ("%file2%.tmp") do (
set "ln2=%%B"
goto :break
)
) else set "ln2="
:break
setlocal enableDelayedExpansion
set "ln1=!ln1:*:=!"
if defined ln2 set "ln2=!ln2:*:=!"
(echo(!ln1!)
(echo(!ln2!)
exit /b
Much better to use jeb's approach if that solution's limitations are not a concern with your files. It currently has the following limitations that could be removed with fairly minor modifications:
Files must have same number of lines
Files must not have blank lines
File1 must not contain ! character
No line in File1 can start with ;
In addition it has the following limitations when reading File2 that are inherent to the SET /P limitations
Lines must be Windows style, ending in carriageReturn lineFeed
Lines cannot exceed 1021 characters (bytes) excluding the line terminators
Control characters will be stripped off the end of each line
An even better solution would be to use something other than batch. There are many possibilities: VBS, JScript, PowerShell, perl ... the list goes on and on.