Stan
Stan

Reputation: 1

Batch file to strip out all lines below a specific line

I am looking to find a batch or VBS solution to strip out lines in a program generated text file with the extension of .trs.

In every .trs file created there is a line that contains the word 'labour'. I need every line after the line that contains the word labour to be deleted.

The .trs files are all stored in c:\export

I have searched for this but some of the commands were well over my head. Could anyone be so kind as to offer me a cut and paste open of the whole batch file, please.

Upvotes: 0

Views: 3355

Answers (2)

Seth McCauley
Seth McCauley

Reputation: 1003

Here is an alternate method to process every .trs file in "C:\export":

@echo off
if not exist "C:\export\*.trs" goto :EOF
if exist "C:\export\queue.tmp" del /q "C:\export\queue.tmp"
for /f "tokens=*" %%A in ('dir /b "C:\export\*.trs"') do (
  for /f "tokens=1,2 delims=:" %%B in ('findstr /inc:"labour" "C:\export\%%A" ^| findstr /n .*') do if "%%B" equ "1" set LineNumber=%%C
  for /f "tokens=1* delims=:" %%D in ('findstr /n .* "C:\export\%%A"') do if %%D lss %LineNumber% echo.%%E>>"C:\export\queue.tmp"
  move /y "C:\export\queue.tmp" "C:\export\%%A">NUL
)

First, I do some error checking to avoid things that would break the script. Next, I pull a list of .trs files stored in C:\export, and loop through each file.

I use 'findstr /inc:"labour" "C:\export\%%A"' to get the line number where "labour" is found in the current file, then pipe it into 'findstr /n .*' to number the results in case more than one match is found.

I then use a for loop with "tokens=1,2 delims=:" to find the first result (if "%%B" equ "1") and store the line number (set LineNumber=%%C).

Next, I use 'findstr /n .* "C:\export\%%A"' to read every line of the file, "tokens=1* delims=:" to separate out the line numbers again, then copy all the data to a temp file until %LineNumber% has been reached. This method of reading the file (using findstr and numbering the lines) also ensures that no blank lines will be skipped by the for loop.

Finally, I replace the original file with the temp file, then loop through to the next file.

I tried to keep the above code as slimmed down as possible. Here is the same script with formatting, comments, visual feedback, and user-definable variables:

@echo off

::Set user-defined Variables
set FilePath=C:\export
set FileType=*.trs
set Keyword=labour

::Check for files to process and exit if none are found
if not exist "%FilePath%\%FileType%" echo Error. No files to process.&goto :EOF

::Delete temp file if one already exists
if exist "%FilePath%\queue.tmp" del /q "%FilePath%\queue.tmp"

::List all files in the above specified destination, then process them one at a time
for /f "tokens=*" %%A in ('dir /b "%FilePath%\%FileType%"') do (
  ::Echo the text without a line feed (so that "Done" ends up on the same line)
  set /p NUL=Processing file "C:\export\%%A"... <NUL

  ::Search the current file for the specified keyword, and store the line number in a variable
  for /f "tokens=1,2 delims=:" %%B in ('findstr /inc:"%Keyword%" "%FilePath%\%%A" ^| findstr /n .*') do (
    if "%%B" equ "1" set LineNumber=%%C
  )>NUL

  ::Output all data from the current file to a temporary file, until the line number found above has been reached
  for /f "tokens=1* delims=:" %%D in ('findstr /n .* "%FilePath%\%%A"') do (
    if %%D lss %LineNumber% echo.%%E>>"%FilePath%\queue.tmp"
  )>NUL

  ::Replace the current file with the processed data from the temp file
  move /y "%FilePath%\queue.tmp" "%FilePath%\%%A">NUL
  echo Done.
)

Upvotes: 3

Jeff K
Jeff K

Reputation: 243

I believe this is the code you are looking for (in a batch file) to remove all of the lines above the word "labour". Let me know if modifications need to be made to the code (such as if there are more than one instance of "labour" in the file).

@echo OFF

setLocal EnableDelayedExpansion

cd C:\export
for /f "delims=" %%I in ('findstr /inc:"labour" "test.trs"') do (
set /A"line=%%I"
)

set count=0

for /f "delims=" %%A in (test.trs) do (
If !count! GEQ %line% goto ExitLoop
echo %%A >>temp.txt
set /A count+=1
echo !count!
)

:ExitLoop

type temp.txt > test.trs
del temp.txt

endlocal

OUTPUT:

test.trs (BEFORE changes)

this
is
a
labour
test
of
the
results

test.trs (AFTER changes)

this
is
a

Upvotes: 3

Related Questions