Useful tool testing "SET /P" reading each line in a file.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

Useful tool testing "SET /P" reading each line in a file.

#1 Post by alan_b » 30 Nov 2011 17:22

Eventually I want to manipulate and sort an array of variables that "SET /P "VAR-ndx=" has extracted from EVERY line in a text file

My immediate need is to ensure that each and every line, including empty blank lines, is extracted by SET /P
For initial testing I simply write each line to the screen for instant debug.

So far I have found 25 ways of using FIND or FINDSTR,
but only 3 of them are valid - the other 22 are defective and fail when confronted by blank lines

I would appreciate suggestions of any other possibilities that merit testing.
After which I will evaluate which is most suitable for my needs.

I started with from code on this site
viewtopic.php?f=3&t=2128&hilit=multiple+lines+in+variable&start=0
That topic included a statement by "dbenham" :-
"This was much more complicated than I thought it would be. Results are NOT as expected."
My understanding is so limited that no result would surprise me :shock:

It was such an obvious assumption that ('find /n "3" %2') was responsible for both search/selection of text and glitches at blank lines,
that I chose not to assume but to test with TWO text files invoked with %1 and %2,
each with five non-blank and unique lines and one blank line but at different positions.

Code: Select all

<%1 (
  for /f %%i in ('find /n "3" %2') do  (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)

File3.txt has the gap between lines 1 and 2,
and File4.txt has the gap between lines 4 and 6.
The output to screen should be 6 lines, and some may be blank,
BUT the file text extraction has failed if the 6th line does not announce
"???? line 6 of 6 ????"

Three ways to make it work :-

Code: Select all

:_D
<%1 (
  for /f %%i in ('findstr /n "^" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)

:_M
<%1 (
  for /f %%i in ('type %2 ^| find /n /v ""') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)

:_S
<%1 (
  for /f %%i in ('find /n /v "" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)

The first of the three above methods, :_D, produced this

E:\T\CCleaner\New># D

--- starting --- --- starting --- --- starting ---

:*********** 30/11/2011 16:16:19.06 *************
MODE = _D. Files :- OUTER = File3.TXT ; INNER = File3.TXT.
:========== findstr /n "^" File3.TXT =======================
file 3 line 1 of 6 but missing line 2 ####

file 3 line 3 of 6 but missing line 2 ####
file 3 line 4 of 6 but missing line 2 ####
file 3 line 5 of 6 but missing line 2 ####
file 3 line 6 of 6 but missing line 2 ####
SUCCESS ---MODE = _D : File3.TXT File3.TXT PROCESSED 6 LINES
:*********** 30/11/2011 16:16:19.10 *************
MODE = _D. Files :- OUTER = File3.TXT ; INNER = File4.TXT.
:========== findstr /n "^" File4.TXT =======================
file 3 line 1 of 6 but missing line 2 ####

file 3 line 3 of 6 but missing line 2 ####
file 3 line 4 of 6 but missing line 2 ####
file 3 line 5 of 6 but missing line 2 ####
file 3 line 6 of 6 but missing line 2 ####
SUCCESS ---MODE = _D : File3.TXT File4.TXT PROCESSED 6 LINES
:*********** 30/11/2011 16:16:19.15 *************
MODE = _D. Files :- OUTER = File4.TXT ; INNER = File3.TXT.
:========== findstr /n "^" File3.TXT =======================
file 4 line 1 of 6 but missing line 4 @ @@@@@
file 4 line 2 of 6 but missing line 4 @ @@@@@
file 4 line 3 of 6 but missing line 4 @ @@@@@

file 4 line 5 of 6 but missing line 4 @ @@@@@
file 4 line 6 of 6 but missing line 4 @ @@@@@
SUCCESS ---MODE = _D : File4.TXT File3.TXT PROCESSED 6 LINES
:*********** 30/11/2011 16:16:19.20 *************
MODE = _D. Files :- OUTER = File4.TXT ; INNER = File4.TXT.
:========== findstr /n "^" File4.TXT =======================
file 4 line 1 of 6 but missing line 4 @ @@@@@
file 4 line 2 of 6 but missing line 4 @ @@@@@
file 4 line 3 of 6 but missing line 4 @ @@@@@

file 4 line 5 of 6 but missing line 4 @ @@@@@
file 4 line 6 of 6 but missing line 4 @ @@@@@
SUCCESS ---MODE = _D : File4.TXT File4.TXT PROCESSED 6 LINES
ALL TESTS DONE

It is of interest that the above Mode :_D extracts text from "OUTER" file "%<1",
and NOT from INNER" file %2 which is the apparent target of the FINDSTR search string.

The other two methods produced similar results.

A sorted list of 25 code portions - Good and Bad :-

for /f %%i in ('find "3" %2') do ( Defective
for /f %%i in ('find "3" ^< %2') do ( Defective
for /f %%i in ('find /n "3" %2') do ( Defective
for /f %%i in ('find /n "3" ^< %2') do ( Defective
for /f %%i in ('find /n /V "" %2') do ( Defective
for /f %%i in ('find /n /v "" ^< %2') do ( SUCCESSFULL ****
for /f %%i in ('find /n /V "3" %2') do ( Defective
for /f %%i in ('find /n /v "3" ^< %2') do ( Defective
for /f %%i in ('find /v /N "3" %2') do ( Defective
for /f %%i in ('findstr "3" %2') do ( Defective
for /f %%i in ('findstr "3" ^< %2') do ( Defective
for /f %%i in ('findstr /n "^" %2') do ( SUCCESSFULL ****
for /f %%i in ('findstr /n "3" %2') do ( Defective
for /f %%i in ('findstr /n "3" ^< %2') do ( Defective
for /f %%i in ('findstr /n /v "^" ^< %2') do ( Defective
for /f %%i in ('findstr /n /v "3" ^< %2') do ( Defective
for /f %%i in ('findstr /V "3" %2') do ( Defective
for /f %%i in ('type %2 ^| find "3" ') do ( Defective
for /f %%i in ('type %2 ^| find /n "3"') do ( Defective
for /f %%i in ('type %2 ^| find /n /v ""') do ( SUCCESSFULL ****
for /f %%i in ('type %2 ^| find /n /v "3"') do ( Defective
for /f %%i in ('type %2 ^| findstr "3" ') do ( Defective
for /f %%i in ('type %2 ^| findstr /n "3"') do ( Defective
for /f %%i in ('type %2 ^| findstr /n /v "^"') do ( Defective
for /f %%i in ('type %2 ^| findstr /n /v "3"') do ( Defective

N.B. The Good portions are SUCCESSFUL in producing an output of 6 lines.

The text files are

File3.txt

Code: Select all

file 3 line 1 of 6 but missing line 2 ####

file 3 line 3 of 6 but missing line 2 ####
file 3 line 4 of 6 but missing line 2 ####
file 3 line 5 of 6 but missing line 2 ####
file 3 line 6 of 6 but missing line 2 ####


File4.txt

Code: Select all

file 4 line 1 of 6 but missing line 4 @    @@@@@
file 4 line 2 of 6 but missing line 4 @    @@@@@
file 4 line 3 of 6 but missing line 4 @    @@@@@

file 4 line 5 of 6 but missing line 4 @    @@@@@
file 4 line 6 of 6 but missing line 4 @    @@@@@


The Principle script is named #.bat,
'#' chosen for launch convenient proximity to the Return Key.

Regardless of any arguments,
this will run four times any chosen find/findstr/etc
using each permutation of Text3.txt and/or text4.txt

#.bat With no arguments compares how "type" and "findstr" give different results.

Arguments A or B or C show other comparisons of FIND, FINDSTR, etc.

The above "sorted list of 25 code portions - Good and Bad" are taken from
Arguments D through to Z plus Z1 plus Z2

An executive script is ##.BAT

##.bat With no arguments will run #.bat for all modes D through to Z2

"##.BAT ALL" runs #.bat for all modes A through to Z2

"##.BAT VALID" runs #.bat for the "good" Modes D, M, and S, which deliver 6 lines of output.

Please note that I launched CMD.EXE and adjusted "properties from my normal screen Buffer size height of 1000 lines to 1100,
After which I could run "##.BAT ALL" and then scroll back and the start was still visible, and the whole buffer could be copy / pasted.

Supervisory script ##.Bat

Code: Select all

@echo off & setlocal EnableDelayedExpansion
CLS

ECHO( > MSG.TXT
IF /I "%1"=="ALL" GOTO ALL
IF /I "%1"=="VALID" GOTO VALID

FOR %%Z IN (D E F G H I J K L M N O P Q R S T U V W X Y Z Z1 Z2) DO CALL # %%Z
GOTO DONE

:VALID
FOR %%Z IN (D M S) DO CALL # %%Z
GOTO DONE

:ALL
FOR %%Z IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Z1 Z2) DO CALL # %%Z
:DONE
TYPE MSG.TXT
ECHO( HAVE A NICE DAY - HIT ANY KEY TO CLOSE
PAUSE


Principle Script #.Bat

Code: Select all

@echo off & setlocal EnableDelayedExpansion & ECHO(

echo --- starting ---  --- starting ---  --- starting ---    & ECHO(

CALL :TESTX File3.TXT File3.TXT _%1
CALL :TESTX File3.TXT File4.TXT _%1
CALL :TESTX File4.TXT File3.TXT _%1
CALL :TESTX File4.TXT File4.TXT _%1

ECHO ALL TESTS DONE

:PAUSE
GOTO :EOF

:TESTX
echo :***********    %DATE% %TIME%    *************
ECHO MODE = %3.  Files :-  OUTER = %1 ; INNER = %2.

SET file=%1

FOR %%Z IN (A B C D E F G H I J K L M O P Q R S T U V W X Y) DO IF /I "%3"=="_%%Z" (
  CALL :_%%Z %1 %2 %3
  FOR /F "tokens=4" %%A IN ("!ln!") DO IF "%%A"=="6" (
    SET MSG=SUCCESS ---MODE = %3 : %1 %2   PROCESSED %%A LINES
    ECHO !MSG! >> MSG.TXT & ECHO !MSG!
  )
  GOTO :EOF
)

echo :====A=======  type  ==================================
<%1 (
  for /f %%i in ('type %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
echo :=====B====  findstr /n "^" %2  =======================
<%1 (
  for /f %%i in ('findstr /n "^" %2') do (
    set "ln=" & set /p "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_A
echo :============  FIND "3"  ==============================
<%1 (
  for /f %%i in ('find /N "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
:_Z1
echo :============  FIND /v "3"  ===========================
<%1 (
  for /f %%i in ('find /v /N "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_B
echo :==========  findstr "3" %2  =======================
<%1 (
  for /f %%i in ('findstr "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
echo :==========  findstr /n "3" %2  =======================
<%1 (
  for /f %%i in ('findstr /n "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_C
echo :============  findstr "3" ============================
<%1 (
  for /f %%i in ('findstr "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
:_Z2
echo :=============  find "3"  =============================
<%1 (
  for /f %%i in ('find "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_D
echo :==========  findstr /n "^" %2  =======================
<%1 (
  for /f %%i in ('findstr /n "^" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_E
echo :==========  findstr /n "3" %2  =======================
<%1 (
  for /f %%i in ('findstr /n "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_F
echo :============  findstr "3" %2  ========================
<%1 (
  for /f %%i in ('findstr "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_G
echo :==========  find /n /V "" %2  =======================
<%1 (
  for /f %%i in ('find /n /V "" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_H
echo :==========  find /n /V "3" %2  =======================
<%1 (
  for /f %%i in ('find /n /V "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_I
echo :============  find /n "3" %2   =======================
<%1 (
  for /f %%i in ('find /n "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_J
echo :==========="('type %2 ^| findstr /n /v "^"')"==========
<%1 (
  for /f %%i in ('type %2 ^| findstr /n /v "^"') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_K
echo :==========="('type %2 ^| findstr /n /v "3"')"==========
<%1 (
  for /f %%i in ('type %2 ^| findstr /n /v "3"') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_L
echo :==========="('type %2 ^| findstr /n "3"')"==========
<%1 (
  for /f %%i in ('type %2 ^| findstr /n "3"') do (
    set "ln=" & set /p "ln=" & set "LINE=result = !ln!" & echo(!ln!
  )
)
GOTO :EOF

:_M
echo :==========="('type %2 ^| find /n /v ""')"==========
<%1 (
  for /f %%i in ('type %2 ^| find /n /v ""') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_N
echo :==========="('type %2 ^| find /n /v "3"')"==========
<%1 (
  for /f %%i in ('type %2 ^| find /n /v "3"') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_o
echo :==========="('type %2 ^| find /n "3"')"==========
<%1 (
  for /f %%i in ('type %2 ^| find /n "3"') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_P
echo :==========="('findstr /n /v "^" ^< %2')"==========
<%1 (
  for /f %%i in ('findstr /n /v "^" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_Q
echo :==========="('findstr /n /v "3" ^< %2')"==========
<%1 (
  for /f %%i in ('findstr /n /v "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_R
echo :==========="('findstr /n "3" ^< %2')"==========
<%1 (
  for /f %%i in ('findstr /n "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_S
echo :==========="('find /n /v "" ^< %2')"==========
<%1 (
  for /f %%i in ('find /n /v "" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_T
echo :==========="('find /n /v "3" ^< %2')"==========
<%1 (
  for /f %%i in ('find /n /v "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF
:_U
echo :==========="('find /n "3" ^< %2')"==========
<%1 (
  for /f %%i in ('find /n "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_V
<%1 (
  for /f %%i in ('find "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_W
<%1 (
  for /f %%i in ('findstr "3" ^< %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_X
echo :=====B======  findstr /V "3" Inner File ==============
<%1 (
  for /f %%i in ('findstr /V "3" %2') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
echo :=====================================================
GOTO :EOF

:_Y
<%1 (
  for /f %%i in ('type %2 ^| find "3" ') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF

:_Z
<%1 (
  for /f %%i in ('type %2 ^| findstr "3" ') do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
GOTO :EOF


Regards
Alan

djangofan
Posts: 23
Joined: 04 Nov 2011 12:28

Re: Useful tool testing "SET /P" reading each line in a fil

#2 Post by djangofan » 11 Jan 2012 14:02

You mention a problem about FIND and FINDSTR not working when confronted with a file with blank lines. The key is to use something like this:

Code: Select all

FOR /F "USEBACKQ delims=" %%A IN (`TYPE.exe "%_FILE%" ^| FIND.exe /V /N ""`) DO (
  SET "LN=%%A"
  SETLOCAL ENABLEDELAYEDEXPANSION
  SET "LN=!LN:*]=!"
  ECHO(!LN!>>"%_FILE%"
  ENDLOCAL
  SET /A COUNT+=1
)

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Useful tool testing "SET /P" reading each line in a fil

#3 Post by Aacini » 11 Jan 2012 18:27

I wrote a very small and simple program that may replace FIND and FINDSTR commands when they are used for this purpose. My PIPE.COM program insert a blank space in empty lines, so all of them may be direclty processed in FOR command.

Code: Select all

@echo off
if not exist pipe.com call :CreatePipe
for /F "delims=" %%i in ('pipe ^< %1') do (
   echo %%i
)
goto :EOF

:CreatePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B
By the while, I would like to make two observations:

1- I don't understand what you attempt to achieve with this code:

Code: Select all

<%1 (
  for /f %%i in ('find /n "3" %2') do  (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
The lines are read from %1 file, but just the amount of lines given by the result of find. You don't use the %%i variable inside the for, so don't matter what the result of find is, the first lines of %1 file are always read. Exactly the same result may be achieved with this code:

Code: Select all

set count=0
for /f %%i in ('find /n "3" %2') do set /A count+=1
<%1 (
  for /L %%i in (1,1,%count%) do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)
In other words: the result of FIND and the reading of the %1 file are unrelated tasks.

2- What you want to do with empty lines in the file? Delete the variable or define the variable with a space as value? Please note that it is not possible to define a variable with an empty value.

djangofan
Posts: 23
Joined: 04 Nov 2011 12:28

Re: Useful tool testing "SET /P" reading each line in a fil

#4 Post by djangofan » 11 Jan 2012 22:27

@Aacini - I had to modify your code a bit to get it to work:

Code: Select all

@echo off
if not exist pipe.com call :CreatePipe
for /F "USEBACKQ delims=" %%i in (`pipe.com ^< %1`) do (
   echo(%%i
)
goto :EOF

:CreatePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B 0

alan_b
Expert
Posts: 357
Joined: 04 Oct 2008 09:49

Re: Useful tool testing "SET /P" reading each line in a fil

#5 Post by alan_b » 12 Jan 2012 05:44

Aacini wrote::CreatePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B
[/code]

Thanks, but I have no need for pipe.com.

N.B. Decades ago I was happy to use Edlin and Debug under DOS 3.2?? to create machine code to run on my single core Intel 8086.
Subsequently up to Windows 98 I might have accepted a peculiar text line of binary from a forum for use on a machine running under Command.com.

When I advanced to XP Home I regretted the demise of Choice.com, and saw on a forum a peculiar text line of binary that created Choice.com,
but many utilities / compilers / assemblers etc that ran under Command.com would crash or malfunction under CMD.EXE under Windows XP.
I chose not to risk taking a peculiar text line of binary and expect Intel Pentium and beyond to be compatible,
and even though the processor may still obey the same instructions,
I am confident that the absolute addresses documented in a 2" thick stack of 13" fan-folded paper will no longer access the HDD appropriately :roll:
Hence when I see a peculiar text line of binary I wonder how many more surprises that will add to what Windows can do by itself :)
I was scarred for life by Windows 95 with its daily BSODs, refusals to shutdown at night,
and rebuking me each morning for not shutting down and then telling me to use ScaDisk to retrieve clusters from files it may have lost :cry:

By the while, I would like to make two observations:

1- I don't understand what you attempt to achieve with this code:

Code: Select all

<%1 (
  for /f %%i in ('find /n "3" %2') do  (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)

The lines are read from %1 file, but just the amount of lines given by the result of find. You don't use the %%i variable inside the for, so don't matter what the result of find is, the first lines of %1 file are always read.
...
In other words: the result of FIND and the reading of the %1 file are unrelated tasks.

I was attempting to gain understanding of what (find ...) was doing and what its capabilities were.
The entire concept of using that sort of code to read each line from a file was new to me.
I could foresee the potential of reading a file and totally discarding some lines,
and perhaps using Find and taking alternative actions on others.
To that end I create two files that were identical apart from the certain specific lines which included "3" in one file and a digit 4" "in the other,
and I ran 4 tests where using invoking my test with the arguments
CALL :MYTEST FILE3 FILE3
CALL :MYTEST FILE3 FILE4
CALL :MYTEST FILE4 FILE3
CALL :MYTEST FILE4 FILE4
From my tests I concluded that my change to either ('find /n "3" %2') or ('find /n /v "3" %2') profoundly affected the quantity of discarded lines,
but unfortunately and understandably all the "bad - reject" lines near the beginning of the file survived, and the "good to use" lines near the end were discarded.
The results were nothing like I hoped. The experiment was a success, I now understand.
Exactly the same result may be achieved with this code:

Code: Select all

set count=0
for /f %%i in ('find /n "3" %2') do set /A count+=1
<%1 (
  for /L %%i in (1,1,%count%) do (
    set "ln=" & set /p "ln=" & echo(!ln!
  )
)


I currently use :-

Code: Select all

SET /A OP=1000 & SET LO=1001
<%1 (
  for /f %%a in ('find /c /v "" ^< %1') do (SET /A VAR=%%a & SET /A HI=LO-1+%%a)
  for /L %%b in (!LO!,1,!HI!) do (
    set "LN=" & set /p "LN="
    rem a load of code
    echo {%%b} {!LN!} Errors found ...
  )
)>out.txt

This has the virtue that %%b starts at 1000, and so long as there are less than 9000 lines within the file "%1"
any output that starts with %%b will always be 4 digits and sortable,
and any variable such as VAR_%%b will always be displayed sensibly by the command SET
I so hate the way that SET insists upon displaying VAR_1. VAR_10, VAR_100, VAR_1000 before showing VAR_2 :)
2- What you want to do with empty lines in the file? Delete the variable or define the variable with a space as value? Please note that it is not possible to define a variable with an empty value.

I have a use for empty lines.
This creates an indexed array of variables ST_%%j , one per line, including blank lines

Code: Select all

SET "START=1"
<%1 (
  for /f %%a in ('find /c /v "" ^< %1') do (SET /A VAR=%%a & SET /A HI=LO-1+%%a)
  for /L %%j in (!LO!,1,!HI!) do (
    SET "ST_%%j=" & SET /P "ST_%%j="
    if "!ST_%%j:~0,1!"=="[" if "!ST_%%j:~-2!"=="*]" (
      REM Start of new definition block
      SET "START=1"
    )
    IF "!START!"=="1" (
      SET /A BID+=1
      SET /A BST=%%j
      ECHO !BID! ] %%j ]  !ST_%%j!
      SET "START=0"
      SET "STFIX=!ST_%%j!"
    )
    SET "END_!BID!=!BST! %%j"
  )
) > #_H.TXT

Subsequently the #_H.TXT file is sorted on the basis of [ header *]
after which all the ST_%%j variables including blanks are written to a new file,
in which each header and its related block of parameters including blank lines,
now appear in [ header *] sequence instead of original adhoc.

Regards
Alan

Post Reply