You have a number of problems with your code :)
1) As you said, your code ignores lines starting with ; - This is due to the default FOR / F EOL option. But your code also separates leading spaces from each line due to "TOKENS = *". You need to install neither EOL nor DELIMS. The syntax is strange, but it works:
for /f delims^=^ eol^= %%i ...
2) You are trying to install and deploy var in a parenthesized block of code. This may not work because the extension occurs when a line is parsed and the entire block of code is parsed immediately. Thus, the value %var% is the value that existed before the execution of the loop. Of course, not what you want. The solution is to use slow expansion. Enter FOR /? from the command line for more information about a delayed extension (about halfway down the help list)
3) For the contents of a variable containing ! will be damaged if it is expanded, if slow expansion is enabled. The solution is to turn on and off delayed expansion as needed in the loop. But this causes a complication, because you need to keep the value of the growing line according to the ENDLOCAL barrier. I use FOR / F to transfer the value across the barrier.
Here is the complete batch of script that should do the job. It is limited in that it cannot process strings exceeding a maximum length of ~ 8191 bytes.
This code has been rewritten to fix a significant error.
@echo off setlocal disableDelayedExpansion set "ln=" set "print=0" for /f delims^=^ eol^= %%i in (myfile.txt) do ( set "var=%%i" setlocal enableDelayedExpansion for /f delims^=^ eol^= %%A in ("!ln!!var!") do ( if "!var:~-1!"==";" ( endlocal echo %%A set "ln=" ) else ( endlocal set "ln=%%A" ) ) )
SET / P Solution
There is a much simpler solution that prints each line immediately, so you donβt have to worry about wrapping the variable through ENDLOCAL. Lines that do not end on ; are printed without newlines using SET / P.
This solution has the following limitations:
1) Lines printed through SET / P will be blank. This restriction is only for Vista and later versions of Windows. This is not a problem for XP.
2) Thanks to David Rumann, now I know that SET / P will fail if the line starts with = . Very unsuccessful: (
@echo off setlocal disableDelayedExpansion set "ln=" for /f delims^=^ eol^= %%i in (myfile.txt) do ( set "var=%%i" setlocal enableDelayedExpansion if "!var:~-1!"==";" (echo !var!) else (<nul set /p ="!var!") endlocal )
hybrid batch / jScript -regex solution (bulletproof?)
I wrote the batch / JScript REPL.BAT hybrid utility, which makes it easy to search and replace regular expressions with the contents of a file. This makes the job easier.
The following command should work on any input without restrictions. It has been updated to support the Windows and Unix lines. And it is much faster than a pure batch solution.
findstr "^." myfile.txt|repl "([^;\r])\r?\n" "$1" m >"outFile.txt"
Here is the REPL.BAT utility. Full documentation is built into the script.
@if (@X)==(@Y) @end var env=WScript.CreateObject("WScript.Shell").Environment("Process"); var args=WScript.Arguments; var search=args.Item(0); var replace=args.Item(1); var options="g"; if (args.length>2) { options+=args.Item(2).toLowerCase(); } var multi=(options.indexOf("m")>=0); var srcVar=(options.indexOf("s")>=0); if (srcVar) { options=options.replace(/s/g,""); } if (options.indexOf("e")>=0) { options=options.replace(/e/g,""); search=env(search); replace=env(replace); } if (options.indexOf("l")>=0) { options=options.replace(/l/g,""); search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1"); replace=replace.replace(/\$/g,"$$$$"); } if (options.indexOf("x")>=0) { options=options.replace(/x/g,""); replace=replace.replace(/\\\\/g,"\\B"); replace=replace.replace(/\\b/g,"\b"); replace=replace.replace(/\\f/g,"\f"); replace=replace.replace(/\\n/g,"\n"); replace=replace.replace(/\\r/g,"\r"); replace=replace.replace(/\\t/g,"\t"); replace=replace.replace(/\\v/g,"\v"); replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g, function($0,$1,$2){ return String.fromCharCode(parseInt("0x"+$0.substring(2))); } ); replace=replace.replace(/\\B/g,"\\"); } var search=new RegExp(search,options); if (srcVar) { WScript.Stdout.Write(env(args.Item(3)).replace(search,replace)); } else { while (!WScript.StdIn.AtEndOfStream) { if (multi) { WScript.Stdout.Write(WScript.StdIn.ReadAll().replace(search,replace)); } else { WScript.Stdout.WriteLine(WScript.StdIn.ReadLine().replace(search,replace)); } } }