Solved FOR loop - variable number of lines to skip

Various / CUSTOM BUILT
August 18, 2015 at 11:45:47
Specs: Windows 7 Professional, Intel i7 4770k, 16GB 1600MHz RAM
I'm working on a batch script where I use a variable to tell the FOR how many lines to skip.
for /f "skip=!lines! tokens=1-3* delims=," %%A in (_!file!.txt)

However this does not seem to work. When I put a static number (replacing !lines! with a number) it works. Is there a way to make this work?

99 little bugs in the code,
99 little bugs.
Take one down, patch it around,
129 little bugs in the code.


See More: FOR loop - variable number of lines to skip

Report •


✔ Best Answer
August 19, 2015 at 19:31:30
Ok, having looked more closely, you need TWO loops (which you prob'ly already know). I made a testing setup and ran the following with fair results:

@echo off & setlocal
:: this version is NOT optimized! It passes through all files for each line
:: until the last line in the longest file is reached.
:: for speed, use ATTRIB to select the files and then disqualify each file
:: when it reaches its last line.
set c=0
:: var TEST is a flag that says no files have any more unprocessed lines
set test=----

:: main loop - pass through all files
:aa

:: clear flag for the next iteration of 'aa'
set test=
:: secondary loop - pass through all files pulling the current line from each
for %%z in (*.txt) do (
call :xx !c! %%z
)
set /a c+=1
if defined test goto :aa
goto :eof

:xx
set /a k=%1+1
:: 'SKIP=0' is not accepted by batch, so this is a workaround
set sk=
if %1 neq 0 set sk=skip=%1
for /f "%sk% tokens=*" %%a in (%2) do (
if "%%a" equ "" echo no more lines in file %2 & goto :eof
echo line %k% from file %2: %%a
pause
:: set flag for loop-repeat: does not have to be %%a. Just needs some/any value
set test=%%a
goto :eof
)



#1
August 18, 2015 at 14:13:41
Advice is useless without context, but if you're in a situation where you can get away with using %lines% instead, do that.

How To Ask Questions The Smart Way


Report •

#2
August 18, 2015 at 14:57:55
Using %lines% does not work.

The files I'm trying to read contains data like this:

08:20,09:00,SS2A_BRU_G
09:00,09:40,SS2A_BRU_G
10:00,10:40,SS2A_DRS_G
10:40,11:20,SS2A_DRS_G
11:45,12:25,HO2A_NO_B

After each loop, %lines% increases by one.

99 little bugs in the code,
99 little bugs.
Take one down, patch it around,
129 little bugs in the code.


Report •

#3
August 18, 2015 at 18:46:58
That's probably because %lines% is assigned within a loop. As Razor pointed out, the exclams won't work but percents will. There are several dodges, but the mainstay is simply to call a sub with the exclam variable:
@echo off & setlocal
set c=0
for ... do (
set /a c+=1
call :xx !c! !file!
)
goto :eof

:xx
for /f "skip=%1 tokens=*" %%a in (_%2.txt) do (
echo %%a
)
::=== end snippet
something like that. marginally tested. You can also user MORE to skip lines:
for /f "tokens=*" %%a in ('MORE +!lines! _!file!.txt') do echo %%a


Report •

Related Solutions

#4
August 18, 2015 at 23:06:30
I tried this:
for /l %%I in (1,1,10) do (
	for /f "skip=%%I tokens=1-3* delims=," %%A in (_!file!.txt) do (
                :: Stuff here
	)
)

I ended up with the command prompt returning

%I tokens=1,-3* delims=," was unexpected at this time

99 little bugs in the code,
99 little bugs.
Take one down, patch it around,
129 little bugs in the code.

message edited by RainBawZ


Report •

#5
August 19, 2015 at 19:31:30
✔ Best Answer
Ok, having looked more closely, you need TWO loops (which you prob'ly already know). I made a testing setup and ran the following with fair results:

@echo off & setlocal
:: this version is NOT optimized! It passes through all files for each line
:: until the last line in the longest file is reached.
:: for speed, use ATTRIB to select the files and then disqualify each file
:: when it reaches its last line.
set c=0
:: var TEST is a flag that says no files have any more unprocessed lines
set test=----

:: main loop - pass through all files
:aa

:: clear flag for the next iteration of 'aa'
set test=
:: secondary loop - pass through all files pulling the current line from each
for %%z in (*.txt) do (
call :xx !c! %%z
)
set /a c+=1
if defined test goto :aa
goto :eof

:xx
set /a k=%1+1
:: 'SKIP=0' is not accepted by batch, so this is a workaround
set sk=
if %1 neq 0 set sk=skip=%1
for /f "%sk% tokens=*" %%a in (%2) do (
if "%%a" equ "" echo no more lines in file %2 & goto :eof
echo line %k% from file %2: %%a
pause
:: set flag for loop-repeat: does not have to be %%a. Just needs some/any value
set test=%%a
goto :eof
)


Report •


Ask Question