Ok so I write in batch files a lot. A while back I asked a question user:cmd on how to copy one part of a running batch file into a new batch file,
Well it works if your going to use it one time in a batch file. My goal is to create multiple large batch files from within a single setup batch. What happens is if they choose to install, then the batch file runs the following.
cls
setlocal EnableDelayedExpansion
color e
::Start of embedded code
set Begin=
for /F "delims=:" %%a in ('findstr /N "^:EMBEDDED_CODE" "%~F0"') do (
if not defined Begin (
set Begin=%%a
) else (
set End=%%a
)
)
::*****************************************************************************
(for /F "skip=%Begin% tokens=1* delims=[]" %%a in ('find /N /V "" "%~F0"') do (
if %%a equ %End% goto :Build-file2
echo(%%b
)) > file1.bat & goto :Build-file2
)
goto :Build-file2
:EMBEDDED_CODE Begin
CODE TO PUT INTO "file1.bat"
:EMBEDDED_CODE End
:Build-file2
cls
setlocal EnableDelayedExpansion
color e
::Start of embedded code
set Begin=
for /F "delims=:" %%a in ('findstr /N "^:EMBEDDED_CODE" "%~F0"') do (
if not defined Begin (
set Begin=%%a
) else (
set End=%%a
)
)
::*****************************************************************************
(for /F "skip=%Begin% tokens=1* delims=[]" %%a in ('find /N /V "" "%~F0"') do (
if %%a equ %End% goto :EOF
echo(%%b
)) > file2.bat & goto :EOF
)
goto :EOF
:EMBEDDED_CODE Begin
CODE TO PUT INTO "file2.bat"
:EMBEDDED_CODE End
The problem that is occurring is instead of it just copying the code between labels EMBEDDED_CODE Begin and EMBEDDED_CODE End in the first FOR loop it copies from EMBEDDED_CODE Begin down to the very bottom of the script puts it in the file I want and then goes to the next FOR loop which repeats the process with different code between the to labels. so file1.bat and file2.bat both contain the exact same code but with the desired file names of file1.bat AND file2.bat.
Why would you expect anything different than the results you are getting? The FINDSTR will search the entire file, so Begin is set to the first occurrence of :EMBEDDED_CODE in the first block of code, and End is set to the last occurrence in the last block of code (last value set wins). You replicate the code, so of course you get the same faulty result two times.
Simply change the labels in your second block of code, perhaps :EMBEDDED_CODE2, and adjust your 2nd FINDSTR accordingly. All should work then.
I often use a slightly different approach that minimizes the amount of file reading. Simply modify all lines from a given embedded block of code with the same unique prefix. Then FINDSTR can directly output the desired lines, and a FOR /F is used to strip off the prefix. You just need the prefix to end with a character that never matches the beginning of your code.
You should be careful about enabling delayed expansion when reading a file with FOR /F. Your embedded code will be corrupted if it contains ! and delayed expansion is enabled. (unless the ! is escaped, but that can be a pain)
#echo off
for %%C in (1 2) do (
for /f "tokens=1* delims=}" %%A in ('findstr /bl ":%%C}" "%~f0"') do echo(%%B
)>file%%C.bat
:1}Your first code block goes here
:1}
:1} Blank lines and indents are preserved
:1}And so are exclamation points!
:2}And here is your second code block
:2}...
echo file1.bat
echo ---------
type file1.bat
echo(
echo(
echo file2.bat
echo ---------
type file2.bat
This will almost do what you need.
This code needs to read twice the input file, first to locate the range of lines to process (findstr line numbering), and second to extract them. In second loop findstr numbering is used again to avoid for /f to compress blank lines and alter line numbering.
On the other hand, the problem with special characters inside extacted text is handled, enabling and disabling delayed expansion as needed.
Maybe not the best performance, but it seems to work. Adapt as needed.
#echo off
setlocal enableextensions enabledelayedexpansion
call :extractEmbedded "Section1" extracted.txt
if not errorlevel 1 (
cls
type extracted.txt
)
exit /b
:extractEmbedded id outputFile
rem prepare environment
setlocal enableextensions enabledelayedexpansion
rem asume failure on execution
set "_return=1"
rem find embedded zone in current file
set "_start="
set "_end="
for /f "tokens=1 delims=:" %%l in ('findstr /n /b /c:":EMBEDDED %~1" "%~f0"') do (
if not defined _start ( set "_start=%%l" ) else ( set "_end=%%l" )
)
rem adjust lines to process
set /a "_start+=0"
set /a "_end-=1"
rem if nothing found, task done
if %_start% GEQ %_end% goto endExtractEmbedded
rem prepare file extraction
if "%_start%"=="0" (set "_skip=" ) else ( set "_skip=skip^=%_start%" )
rem extract proper area of file to output file
(for /f tokens^=^*^ %_skip%^ eol^= %%l in ('findstr /n "^" "%~f0"') do if !_start! LSS !_end! (
setlocal disabledelayedexpansion
set "_line=%%l"
setlocal enabledelayedexpansion
echo(!_line:*:=!
endlocal & endlocal
set /a "_start+=1"
))>"%~2"
rem everything ok
set "_return=0"
:endExtractEmbedded
rem exit with errorlevel
endlocal & exit /b %_return%
:EMBEDDED Section1
This is a section; of embedded!!! code
that needs to be extracted to generate
a new file to be processed.
TEST: !""$%&/()=?¿^*[];,:-\|
:EMBEDDED Section1
Related
In below code i am tring to fetch the line no of string "AXX0000XXXA" from file data.txt,then fetching line by line and printing target.txt file,in between if the line reach the find line no i am adding one more line from file temp.txt.The code is working fine with the less nos of records(tested with 150 lines-File Size 100 kb),but when i am processing with 50K records(File Size 25MB) it is taking more then 25 minutes to process.could you please help me how i will process same in less time.
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set find_line=%%a)
set /a counter=0
for /f "usebackq delims=" %%b in (`"findstr /n ^^ C:\Users\23456\Desktop\data.txt"`) do (
set curr_line=%%b
set /a counter=!counter!+1
if !counter! equ !find_line! (
type temp.txt >> target.txt
)
call :print_line curr_line
)
endlocal
:print_line
setlocal enabledelayedexpansion
set line=!%1!
set line=!line:*:=!
echo !line!>>target.txt
endlocal
Your code uses three Batch file constructs that are inherently slow: call command, >> append redirection and setlocal/endlocal, and these constructs are executed once per each file line! It would be faster to include the subroutine into the original code to avoid the call and setlocal commands, and an echo !line!>>target.txt command imply open the file, search for the end, append the data and close the file, so it is faster to use this construct: (for ...) > target.txt that just open the file once. An example of a code with such changes is in Compo's answer.
This is another method to solve this problem that may run faster when the search line is placed towards the beginning of the file:
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF
:processFile
rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
set /P "line="
echo !line!
)
rem Insert the additional line
type temp.txt
rem Copy the rest of lines
findstr ^^
exit /B
This should create target.txt with content matching data.txt except for an inserted line taken from tmp.txt immediately above the line matching the search string, AXX0000XXXA.
#Echo Off
Set "fSrc=C:\Users\23456\Desktop\data.txt"
Set "iSrc=temp.txt"
Set "sStr=AXX0000XXXA"
Set "fDst=target.txt"
Set "iStr="
Set/P "iStr="<"%iSrc%" 2>Nul
If Not Defined iStr Exit/B
Set "nStr="
For /F "Delims=:" %%A In ('FindStr/N "%sStr%" "%fSrc%" 2^>Nul') Do Set "nStr=%%A"
If Not Defined nStr Exit/B
( For /F "Tokens=1*Delims=:" %%A In ('FindStr/N "^" "%fSrc%"') Do (
If "%%A"=="%nStr%" Echo %iStr%
Echo %%B))>"%fDst%"
I have made it easy for you to change your variable data, you only need to alter lines 3-6.
I have assumed that this was your intention, your question was not clear, please accept my apologies if I have assumed incorrectly.
Let me start off by saying I am very new to this, and what little code I have cobbled together I found on this site.
In the end I need a batch that when ran will grab each folder name in a parent dir. and copy it to a text file named label1, label2, ect.
I started with pulling the lines from a directory list in a text file. I can get it to echo the last line to a file using Seth's code from this post
Windows Batch file to echo a specific line number
I made some modifications to try to put it in a loop and now I get nothing out.
If anyone can help me it would be much appreciated. Here is my code so far.
set /a "x=1"
set /a "lines=91"
:while1
if %x% leq %lines% (
for /f "tokens=*" %%a in ('findstr /n .* "Y:\Test\foldernametest.txt"') do (
set "FullLine=%%a"
for /f "tokens=1* delims=:" %%b in ("%%a") do (
setlocal enabledelayedexpansion
set "LineData=!FullLine:*:=!"
if "%%b" equ "%1" echo(!LineData!
echo title=!linedata! > Lable%x%.dat
set /a "x= x+1"
endlocal
goto :while1
)
)
setlocal enabledelayedexpansion
set /a x=1
set /a lines=91
:while1
if %x% leq %lines% (
for /f "tokens=*" %%a in ('findstr /n .* "Y:\Test\foldernametest.txt"') do (
for /f "tokens=1* delims=:" %%b in ("%%a") do (
if "%%b" equ "%x%" (
echo(%%c
echo title=%%c > Lable%x%.dat
set /a x= x+1
goto while1
)
)
)
endlocal
I'm reasonably sure this will work, as would
setlocal enabledelayedexpansion
set /a x=1
set /a lines=91
:while1
if %x% leq %lines% (
for /f "tokens=1* delims=:" %%a in ('findstr /n .* "Y:\Test\foldernametest.txt"') do if %%a==%x% (
echo(%%b
echo title=%%b > Lable%x%.dat
set /a x= x+1
goto while1
)
)
endlocal
The issue with your code is that endlocal terminates a setlocal and all of the environment changes that have taken place since the setlocal are backed out - the environment is restored to what it was when the setlocal was executed.
The consequence is that with your code, you are incrementing x (a grand name for a variable) and then the increment is backed out when the endlocal is executed.
So - put the entire routine in a setlocal/endlocal bracket. This has other advanteages - like if you execute a setlocal immediately after #echo off, then when the routine terminates, the environment is returned to its original state - it does not accumulate changes (normally additions of variables) as more and more batches are run.
Some of the other changes I've made are cosmetic. the quotes in a set /a are superfluous and so is the colon in a goto (with the sole exception of goto :eof)
Another problem you have was %1 (meaning "the first parameter to the routine") where you probably meant "%x%".
In the first code fragment, the output of the findstr is assigned to %%a and the inner for assigns that part of the findstr before the delimiter to %%b and that after to %%c. You evidently want to pick the line %%b equal to %x% so the code makes the comparison and if equal, outputs %%c (rest of line) and title=%%c to the file made from Lable and the line number. (You've spelled label incorrectly); then increments x and tries again.
The second piece of code is a simplification of the first. The line is read from the file and numbered, then split directly on the colon; %%a gets the number, %%b the rest of the line, so if %%a is the same as the number %x% then we want to do something (no quotes required, since %%a is a simple numeric string and x will also be numeric because it's never assigned to a string containing separators or empty).
The thing-to-be-done is to echo the line from the file (in %%b, bump the line number and start again...
I made a Batch script to rename a large amount of files. It takes their name and searches for it in a text document, copies the line and takes the data I need from it and then renames the file.
It seems to work fine for the most part, but I can't check to see how it's doing because it is constantly producing errors/warnings in the console.
#echo off
set ogg=.ogg
Setlocal EnableDelayedExpansion
for %%a in (*.ogg) do (
set fileNameFull=%%a
set fileName=!fileNameFull:~0,-4!
for /F "delims=" %%a in ('findstr /I !fileName! strings.txt') do (
endlocal
set "stringLine=%%a%ogg%"
)
Setlocal EnableDelayedExpansion
set fullString=!stringLine:~26!
ren %%a "!fullString!"
)
pause
The code works, I'd just like to be able to track progress, as 10,000s of files are being renamed at a time and I've no indication of how far along the process is.
The errors are:
"FINDSTR: Cannot open [...]"
"The syntax of the command is incorrect."
#echo off
Setlocal EnableDelayedExpansion
for %%a in (*.ogg) do (
for /F "delims=" %%q in ('findstr /I /L /c:"%%~na" strings.txt') do (
set "stringLine=%%q"
)
ECHO ren "%%a" "!stringLine:~26!.ogg"
)
pause
This code should be equivalent, but fixed, to the code you've posted.
Fixes:
Removed the endlocal/setlocal complication - not required
changed the inner `for` metavariable - must not be duplicate `%%a`
Changed the `findstr` switches - add `/L` for literal and `/c:` to force single token in case of a separator-in-name; use `%%~na` to specify "the name part of `%%a`" to avoid the substringing gymnastics.
removed said gymnastics
Removed 2-stage string manipulation of destination filename
Removed superfluous setting of `ogg`
The resultant code should duplicate what you have originally, except that it will simply report the rename instruction. You should test this against a small representative sample to verify.
for counting/progress:
set /a count=0
for %%a in (*.ogg) do (
for /F "delims=" %%q in ('findstr /I /L /c:"%%~na" strings.txt') do (
set "stringLine=%%q"
)
ECHO ren "%%a" "!stringLine:~26!.ogg"
set /a count +=1
set /a stringline= count %% 1000
if %stringline% equ 0 echo !count! Processed
)
pause
which should show you progress each 1000.
You could use
if %stringline% equ 0 echo !count! Processed&pause
to wait for user-action before progressing...
BTW -I'm making the assumption that the newname is from column 27+ in your file, since you've not shown us a sample.Also, you should be aware that a simple findstr would locate the target string as a substring anywhere within the file - either as the newname or the oldname. If you invoke the /B switch on the findstr, then the string will match at the very beginning of the line only.
So I'm building a messaging program in batch (I know, it's newbish) and the program takes user input, puts it in my .txt file log.txt, and types it on the screen. I want the output to look like this...
Title
----------------------
contents
of
the
file
here
----------------------
User input here>>
This may seem simple, but the file will be constantly updated by users and I want the program to only display a range of lines to keep that message area stays the same size. I found a simple program to display specific lines, but I can't make them move down one line each time log.txt is changed. Here it is:
#setlocal enableextensions enabledelayedexpansion
#echo off
set lines=1
set curr=1
for /f "delims=" %%a in ('type bob.txt') do (
for %%b in (!lines!) do (
if !curr!==%%b echo %%a
)
set /a "curr = curr + 1"
)
endlocal
(By the way, this program is called lines.bat. I just call it in cmd to test it.)
To return a defined number of lines starting from a certain line number, you can do the following:
#echo off
setlocal EnableExtensions
rem define the (path to the) text file here:
set "TEXT_FILE=log.txt"
rem define the line number here:
set /A "LINE_NUMBER=1"
rem define the number of lines here:
set /A "LINE_COUNT=5"
set /A "LINE_LIMIT=LINE_NUMBER+LINE_COUNT-1"
for /F delims^=^ eol^= %%L in ('findstr /N /R "^" "%TEXT_FILE%"') do (
setlocal DisableDelayedExpansion
set "LINE=%%L"
setlocal EnableDelayedExpansion
for /F "tokens=1 delims=:" %%N in ("!LINE!") do set "LNUM=%%N"
set "LINE=!LINE:*:=!"
if !LNUM! GEQ !LINE_NUMBER! (
if !LNUM! LEQ !LINE_LIMIT! (
echo !LINE!
)
)
endlocal
endlocal
)
endlocal
The findstr command with the /R "^" search pattern returns all lines. The findstr switch /N lets every line precede with a line number (starting from 1) and a colon. The : is used to split the line in two parts: the first part representing the line number is checked whether it is in the range to be returned; the second part is the original line of text which is simply output in case. Even empty lines are taken into account.
You might ask why not simply using the above mentioned : as a delims delimiter option for for /F, but this would cause problems with lines of text starting with :.
The toggling of delayed expansion is necessary to avoid trouble with special characters like !, for instance.
To return the last defined number of lines, the following approach can be used:
#echo off
setlocal EnableExtensions
rem define the (path to the) text file here:
set "TEXT_FILE=log.txt"
rem define the number of lines here:
set /A "LINE_COUNT=5"
for /F "tokens=1 delims=:" %%L in ('findstr /N /R "^" "%TEXT_FILE%"') do (
set /A "LINE_SKIP=%%L"
)
set /A "LINE_SKIP-=LINE_COUNT"
if %LINE_SKIP% GTR 0 (
set "LINE_SKIP=skip^=%LINE_SKIP%^ "
) else (
set "LINE_SKIP="
)
for /F %LINE_SKIP%delims^=^ eol^= %%L in ('findstr /N /R "^" "%TEXT_FILE%"') do (
setlocal DisableDelayedExpansion
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:*:=!"
echo !LINE!
endlocal
endlocal
)
endlocal
Again, the findstr /N /R "^" command is used. But here, we have an additional for /F loop first, which merely counts the number of lines in the text file, extracting the line number preceded by findstr. The second for /F loop is quite similar to the above approach, but a dynamic skip option is introduced, so that the loop starts iterating through the last lines only; the rest is almost the same as above, except that the conditions concerning the current line number have been removed.
I know I could do the counting of lines also by using find /C /V "" rather than looping through the findstr /N /R "^" output, but if there are one or more empty lines at the end of the file, find returns a number one less as the findstr method, so I went for findstr consistently.
Also here, delayed expansion is toggled to avoid trouble with the ! character.
Is it possible to remove duplicate rows from a text file? If yes, how?
Sure can, but like most text file processing with batch, it is not pretty, and it is not particularly fast.
This solution ignores case when looking for duplicates, and it sorts the lines. The name of the file is passed in as the 1st and only argument to the batch script.
#echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "sorted=%file%.sorted"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
sort "%file%" >"%sorted%"
>"%deduped%" (
set "prev="
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%sorted%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
if /i "!ln!" neq "!prev!" (
endlocal
(echo %%A)
set "prev=%%A"
) else endlocal
)
)
>nul move /y "%deduped%" "%file%"
del "%sorted%"
This solution is case sensitive and it leaves the lines in the original order (except for duplicates of course). Again the name of the file is passed in as the 1st and only argument.
#echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "line=%file%.line"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
>"%deduped%" (
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
>"%line%" (echo !ln:\=\\!)
>nul findstr /xlg:"%line%" "%deduped%" || (echo !ln!)
endlocal
)
)
>nul move /y "%deduped%" "%file%"
2>nul del "%line%"
EDIT
Both solutions above strip blank lines. I didn't think blank lines were worth preserving when talking about distinct values.
I've modified both solutions to disable the FOR /F "EOL" option so that all non-blank lines are preserved, regardless what the 1st character is. The modified code sets the EOL option to a linefeed character.
New solution 2016-04-13: JSORT.BAT
You can use my JSORT.BAT hybrid JScript/batch utility to efficiently sort and remove duplicate lines with a simple one liner (plus a MOVE to overwrite the original file with the final result). JSORT is pure script that runs natively on any Windows machine from XP onward.
#jsort file.txt /u >file.txt.new
#move /y file.txt.new file.txt >nul
you may use uniq http://en.wikipedia.org/wiki/Uniq from UnxUtils http://sourceforge.net/projects/unxutils/
Some time ago I found an unexpectly simple solution, but this unfortunately only works on Windows 10: the sort command features some undocumented options that can be adopted:
/UNIQ[UE] to output only unique lines;
/C[ASE_SENSITIVE] to sort case-sensitively;
So use the following line of code to remove duplicate lines (remove /C to do that in a case-insensitive manner):
sort /C /UNIQUE "incoming.txt" /O "outgoing.txt"
This removes duplicate lines from the text in incoming.txt and provides the result in outgoing.txt. Regard that the original order is of course not going to be preserved (because, well, this is the main purpose of sort).
However, you sould use these options with care as there might be some (un)known issues with them, because there is possibly a good reason for them not to be documented (so far).
The Batch file below do what you want:
#echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
if "%%a" neq "!prevLine!" (
echo %%a
set "prevLine=%%a"
)
)
If you need a more efficient method, try this Batch-JScript hybrid script that is developed as a filter, that is, similar to Unix uniq program. Save it with .bat extension, like uniq.bat:
#if (#CodeSection == #Batch) #then
#CScript //nologo //E:JScript "%~F0" & goto :EOF
#end
var line, prevLine = "";
while ( ! WScript.Stdin.AtEndOfStream ) {
line = WScript.Stdin.ReadLine();
if ( line != prevLine ) {
WScript.Stdout.WriteLine(line);
prevLine = line;
}
}
Both programs were copied from this post.
set "file=%CD%\%1"
sort "%file%">"%file%.sorted"
del /q "%file%"
FOR /F "tokens=*" %%A IN (%file%.sorted) DO (
SETLOCAL EnableDelayedExpansion
if not [%%A]==[!LN!] (
set "ln=%%A"
echo %%A>>"%file%"
)
)
ENDLOCAL
del /q "%file%.sorted"
This should work exactly the same. That dbenham example seemed way too hardcore for me, so, tested my own solution. usage ex.: filedup.cmd filename.ext
Pure batch - 3 effective lines.
#ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (q34223624.txt) DO SET $%%a=Y
(FOR /F "delims=$=" %%a In ('set $ 2^>Nul') DO ECHO %%a)>u:\resultfile.txt
GOTO :EOF
Works happily if the data does not contain characters to which batch has a sensitivity.
"q34223624.txt" because question 34223624 contained this data
1.1.1.1
1.1.1.1
1.1.1.1
1.2.1.2
1.2.1.2
1.2.1.2
1.3.1.3
1.3.1.3
1.3.1.3
on which it works perfectly.
Did come across this issue and had to resolve it myself because the use was particulate to my need.
I needed to find duplicate URL's and order of lines was relevant so it needed to be preserved. The lines of text should not contain any double quotes, should not be very long and sorting cannot be used.
Thus I did this:
setlocal enabledelayedexpansion
type nul>unique.txt
for /F "tokens=*" %%i in (list.txt) do (
find "%%i" unique.txt 1>nul
if !errorlevel! NEQ 0 (
echo %%i>>unique.txt
)
)
Auxiliary: if the text does contain double quotes then the FIND needs to use a filtered set variable as described in this post: Escape double quotes in parameter
So instead of:
find "%%i" unique.txt 1>nul
it would be more like:
set test=%%i
set test=!test:"=""!
find "!test!" unique.txt 1>nul
Thus find will look like find """what""" file and %%i will be unchanged.
I have used a fake "array" to accomplish this
#echo off
:: filter out all duplicate ip addresses
REM you file would take place of %1
set file=%1%
if [%1]==[] goto :EOF
setlocal EnableDelayedExpansion
set size=0
set cond=false
set max=0
for /F %%a IN ('type %file%') do (
if [!size!]==[0] (
set cond=true
set /a size="size+1"
set arr[!size!]=%%a
) ELSE (
call :inner
if [!cond!]==[true] (
set /a size="size+1"
set arr[!size!]=%%a&& ECHO > NUL
)
)
)
break> %file%
:: destroys old output
for /L %%b in (1,1,!size!) do echo !arr[%%b]!>> %file%
endlocal
goto :eof
:inner
for /L %%b in (1,1,!size!) do (
if "%%a" neq "!arr[%%b]!" (set cond=true) ELSE (set cond=false&&goto :break)
)
:break
the use of the label for the inner loop is something specific to cmd.exe and is the only way I have been successful nesting for loops within each other. Basically this compares each new value that is being passed as a delimiter and if there is no match then the program will add the value into memory. When it is done it will destroy the target files contents and replace them with the unique strings