Leo92
Leo92

Reputation: 744

Processing an input file in batch

I want to write a batch file to read an input text file, extract information from it put it in an output file.

  1. Each line in the input file has different information so I want the batch to loop through each line.
  2. I want to extract certain information from the input file and discard the rest.
  3. The input file can have any number of lines.
  4. I want to leave an error message if the input line has no useful information.
  5. I need two counters, the first telling the number of lines in the input file, and the second telling the number of lines in the output file (without counting empty lines) .
  6. I want the batch to treat special characters like normal letters.

For example:

FILE_NAME=apple FILE_SIZE=312     C=fwef sdf asdetg

FILE_SIZE=7867 C=ehtrghr  FILE_NAME=sea&ocean G=tryr    yujg
C=gert FILE_NAME=chair=12 tgrgd sfsf FILE_SIZE=66
dfgg ertergf C=ert A=344

fgdfg FILE_NAME=cat

I want to extract only the FILE_NAME=XXX and FILE_SIZE=XXX part, discarding everything else in that line. The output should be:

-name apple -size 312
-name sea&ocean -size 7867
-name chair=12 -size 66
ERROR!!!
-name cat

 input_count=5 and output_count=4

Upvotes: 1

Views: 3448

Answers (1)

Eitan T
Eitan T

Reputation: 32930

People don't give enough credit to batch scripts. Try this:

@echo off
setlocal enableDelayedExpansion
set INPUT_FILE=input.txt
set OUTPUT_FILE=output.txt
set INPUT_COUNT=0
set OUTPUT_COUNT=0

:: Read the input file
for /f "tokens=*" %%s in (%INPUT_FILE%) do call :ParseLine "%%s"
echo. >>%OUTPUT_FILE%
echo input_count=!INPUT_COUNT! and output_count=!OUTPUT_COUNT! >>%OUTPUT_FILE%
exit /b

:: Parse one line and write to output
:ParseLine
set "str=%~1"
set ^"str=!str: =^

!"
set file_name=
set file_size=
for /f "eol=  tokens=1,2 delims==" %%a in ("!str!") do (
    set "tag=%%a"
    set "value=%%b"
    if "!tag!" equ "FILE_NAME" set "file_name=-name !value!"
    if "!tag!" equ "FILE_SIZE" set "file_size=-size !value!"
)
set /a input_count+=1
if "!file_name!" equ "" if "!file_size!" equ "" (
    echo ERROR^^!^^!^^! >>%OUTPUT_FILE%
    goto Done
)
echo.!file_name! !file_size! >>%OUTPUT_FILE%
set /a output_count+=1
:Done

Here's a little explanation about what this does:

  1. The first for loop reads the file line by line, the contents of each line being sent as input arguments to the ParseLine subroutine.
  2. The ParseLine subroutine receives each line in str and iterates through its space-separated words (using jeb's advanced method described here).
    The logic of the subroutine loop is pretty straightforward: it breaks each word into tag (the text that precedes =) and value (the text that follows =), and sets file_name and file_size accordingly.

I believe that this method can handle pretty much any input file, with or without special characters.

Upvotes: 2

Related Questions