I need to loop through every line in a text file, and still have the empty lines. The common solution I could find is as follows:
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%textfile%"') do ( call :IsLabel _return "%%b" )
This will prefix every line with the line number and colon character, example:
21:R 30 35 89jtj3 G)(#G_ 23ty9ug9dg
The problem is that, if the first character is a colon, (:
), it will get dropped due to delims=:
in the for
loop.
So 30::mylabel
becomes just mylabel
instead of :mylabel
.
Is there a way to make findstr
use another character than colon perhaps?
-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-EDIT-
Since, no matter what, there will be extra characters to remove, I think that the best course of action is to dump the entire file into an array. Then remove the characters from that array.
So what is needed is a "FileToArray" function that takes a filename and array name and populates the array with the content of that file.
My first attempt, based on @Mofi's answer is as follows
::Usage Call :SimpleFileToArray OutputArray Filename
:SimpleFileToArray
set "_FTA_Output=%~1"
set "_FTA_ubound=1"
setlocal enabledelayedexpansion
set _FTA_localscope=true
for /f delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /n "^" "%~2"') do (
set _FTA_buffer=%%I
set %_FTA_Output%[!_FTA_ubound!]=!_FTA_buffer:*:=!
set /a "_FTA_ubound+=1"
)
for /F "delims=" %%a in ('set %_FTA_Output% 2^>nul') do endlocal & set %%a
if defined _FTA_localscope endlocal
GoTo :EOF
(execution time, 4 second for 1600 lines on slow computer)
This version almost works, however, as @Mofi points out, is that doing this you lose all the ! characters on the line
set _FTA_buffer=%%I
@Mofi then suggests to perform the removal of the line numbers in a setlocal inside the for loop instead. In the example, this works because the data is echo'd out directly and doesn't need to be kept in a variable outside of setlocal
So, I tried this variant with a setlocal / endlocal inside the for loop
::Usage Call :SimpleFileToArray OutputArray Filename
:SimpleFileToArray
set "_FTA_Output=%~1"
set "_FTA_ubound=1"
for /f delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /n "^" "%~2"') do (
set _FTA_buffer=%%I
setlocal enabledelayedexpansion
set _FTA_buffer=!_FTA_buffer:*:=!
echo set %_FTA_Output%[!_FTA_ubound!]=!_FTA_buffer!
set %_FTA_Output%[!_FTA_ubound!]=!_FTA_buffer!
set /a "_FTA_ubound+=1"
set _FTA_ubound=!_FTA_ubound!
endlocal & set /a "_FTA_ubound=%_FTA_ubound%" & set %_FTA_Output%[%_FTA_ubound%]=%_FTA_buffer%
)
GoTo :EOF
(same execution time)
Unfortunately, this does not set the outputarray values.
If I echo(%_FTA_buffer% , I can see the values get passed substituted properly but can't get them out of that endlocal
I tried other permutations
::Usage Call :SimpleFileToArray OutputArray Filename
:SimpleFileToArray
set "_FTA_Output=%~1"
set "_FTA_ubound=1"
setlocal enabledelayedexpansion
set _FTA_localscope=true
for /f delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /n "^" "%~2"') do (
setlocal disabledelayedexpansion
set _FTA_buffer=%%I
setlocal enabledelayedexpansion
set /a "_FTA_ubound+=1"
endlocal & endlocal & set /a "_FTA_ubound=!_FTA_ubound!" & set %_FTA_Output%[!_FTA_ubound!]=!_FTA_buffer:*:=!
)
for /F "delims=" %%a in ('set %_FTA_Output% 2^>nul') do endlocal & set %%a
if defined _FTA_localscope endlocal
GoTo :EOF
(this does not set any values)
::Usage Call :SimpleFileToArray OutputArray Filename
:SimpleFileToArray
set "_FTA_Output=%~1"
set "_FTA_ubound=1"
setlocal enabledelayedexpansion
set _FTA_localscope=true
for /f delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /n "^" "%~2"') do (
setlocal disabledelayedexpansion
set _FTA_buffer=%%I
endlocal & set %_FTA_Output%[!_FTA_ubound!]=!_FTA_buffer:*:=!
set /a "_FTA_ubound+=1"
)
for /F "delims=" %%a in ('set %_FTA_Output% 2^>nul') do endlocal & set %%a
if defined _FTA_localscope endlocal
GoTo :EOF
This sets every array item to *:=
example
LinesArray[999]=*:=
To launch this function, I use this test function
:SimpleFileToArray-DEMO
Call :ClearVariablesByPrefix _FTA LinesArray
echo start SimpleFileToArray %time%
Call :SimpleFileToArray LinesArray batchsample.bat
echo end SimpleFileToArray %time%
GoTo :EOF