batch-filecmdscripting

How to read a .txt file in reverse order using Batch


I have a data.txt file that I parse through in my .cmd script, I go through it from the first line to the last. I want to start from the last line and go to the first instead.

FOR /F "EOL=; TOKENS=1 DELIMS=" %%r IN (datafile) DO (CALL :DeleteFolder %%r)

How would I be able to reverse the order in which it is read?

I have tried finding the syntax for the "FOR /....." but it seems impossible to find good documentation for .cmd or batch files (question within a question, is a .cmd file the same as a batch file and a .bat file, the syntax seems to be the same and whenever I search for .cmd file it will show me batch file help).

This is the sample data file I am working with now for testing purposes, the real data file will be a couple hundred lines and changes frequently, it should be around 300 lines. It is basically dictating a folder and subfolder structure.

; This is a comment line
DEV1
DEV2
DEV3
DEV4
DEV5
DEV6
DEV7
DEV8
DEV9
DEV10
; This is a comment line

Solution

  •     @echo off
        setlocal
        
        set "file=data.txt"
        REM create a file with line numbers (while removing comments):
        findstr /bv ";" "%file%" | findstr /n "^" > "%file%.tmp"
        
        REM find number of lines:
        for /f %%i in ('type "%file%.tmp"^|find /c /v ""') do set lines=%%i
        
        REM process them in reverse order:
        for /l %%i in (%lines%,-1,1) do (
          for /f "tokens=1,* delims=:" %%x in ('findstr /b "%%i:" "%file%.tmp"') do (
            echo processing line number %%x:        %%y
          )
        )
        del "%file%.tmp"
    

    There is a read operation for each line (plus one to create the tempfile and one to count the lines), but just a single write operation (creating the tempfile). No data is held in memory (except the line to process), so there is no danger of exceeding space for variables or recursion limit.

    Empty lines are kept (there are none in your sample data), but can be filtered out with another findstr, when needed.