sjoy
sjoy

Reputation: 502

How to use for /f skip to delete lines from beginning of text file

Still suffering from expansion dysfunction, I fear. I'm trying to strip lines GTR than 100 from the beginning of log files. The following looks to me like it should work, but as shown, the for /f "skip" near end isn't working. Can someone kindly explain what's wrong here? Thank you!

@echo off
SETLOCAL EnableDelayedExpansion

Set "logfile=abc.log"

rem ~ Get line count and exit if not greater 100
  For /f %%G in ('Type "!logfile!"^|Find "" /v /c') Do SET /a linecount=%%G
  If not %linecount% GTR 100 exit /b

rem ~ get number lines to skip
  set /a skiplines=!linecount! -100
  echo. &echo logfile=%logfile%, linecount=%linecount%, skiplines=%skiplines%
  :: Above displays: logfile=abc.log, linecount=243, skiplines=143

:: HERE'S THE PROBLEM:

rem ~ skip the first %skiplines% in file and write remaining to temp
  for /f "skip=!skiplines! delims=*" %%H in ("!logfile!") do echo %%H >>newfile.tmp

:: Above give error: "!skiplines! delims=*" was unexpected at this time."

  for /f "skip=%skiplines% delims=*" %%H in ("!logfile!") do echo %%H >>newfile.tmp

:: (as expected, above writes 0 to newfile.tmp)

One Solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I'm editing to show this one-line solution prominently along with accepted answer. The code required usebackq, as included in @Magoo answer. This works:

for /f "usebackqskip=%skiplines% delims=*" %%H in ("!logfile!") do echo %%H>>newfile.tmp

Upvotes: 0

Views: 602

Answers (2)

ths
ths

Reputation: 2942

probably because your file is in !logfile!, not !countfile!. the %skiplines% should work, since it's not used in the same statement as it is set.

Upvotes: 1

Magoo
Magoo

Reputation: 80033

It's a matter of when !var! and %var% are evaluated in the process. %var% is evaluated (substituted) first but !var! is only evaluated after the loop 's conditions are established, hence !var! is not expected in that position.

The solution is to only use !var! as intended, (within loops) where the value is determined at run-time, not parse-time. Use %var% to access the parse-time value. Don't treat !var! and %var% as equivalent outside of loops. For come commands they effectively are, but not all.

BTW - watch what happens when linecount is exacly 100. SKIP does not like 0. I'd change the GTR to GEQ if I were you...


Here's a routine that should demonstrate what's happening. It uses my work area - you'd need to alter it for your system, no doubt.

@ECHO OFF
SETLOCAL
:: Just setting up data
SET "sourcedir=U:\sourcedir"
Set "logfile=abc.log"

PUSHD "%sourcedir%"
(
 FOR /l %%a iN (1,1,99) DO ECHO line %%a
)>"%logfile%"

CALL :process
>>"%logfile%" ECHO line 100
CALL :process
>>"%logfile%" ECHO line 101
CALL :process
>>"%logfile%" ECHO line 102
CALL :process

popd
GOTO :eof

:process

For /f %%G in ('type "%sourcedir%\%logfile%"^|Find "" /v /c') Do SET /a linecount=%%G

ECHO %linecount% lines IN log file

IF %linecount% leq 100 EXIT /b

ECHO MORE than 100 lines!!

SET /a skiplines=linecount - 100
SET /a skiplines2=%linecount% - 100
ECHO ------- observe response from this instruction
SET /a skiplines3=!linecount! - 100
ECHO ------- this is because of the sequence-of-evaluation-and-substitution

SET skipline

:: delete the output file
DEL newfile.tmp >NUL 2>NUL

FOR /f "usebackqskip=%skiplines% delims=*" %%H IN ("%sourcedir%\%logfile%") DO ECHO %%H >>newfile.tmp
ECHO =====================
ECHO after skipping %skiplines% of %logfile% result is
TYPE newfile.tmp
ECHO =====================
EXIT /b

The result should be

99 lines IN log file
100 lines IN log file
101 lines IN log file
MORE than 100 lines!!
------- observe response from this instruction
Missing operator. 
------- this is because of the sequence-of-evaluation-and-substitution
skiplines=1
skiplines2=1
skiplines3=0
=====================
after skipping 1 of abc.log result is
line 2 
line 3 
...
line 100 
line 101 
=====================
102 lines IN log file
MORE than 100 lines!!
------- observe response from this instruction
Missing operator.
------- this is because of the sequence-of-evaluation-and-substitution
skiplines=2
skiplines2=2
skiplines3=0
=====================
after skipping 2 of abc.log result is
line 3 
line 4 
...
line 101 
line 102 
=====================

Upvotes: 1

Related Questions