1

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
Eitan T
  • 32,660
  • 14
  • 72
  • 109
Leo92
  • 724
  • 4
  • 16
  • 29
  • I know this isn't batch file method so probably not suitable, but awk and sed are both (linux) command line tools for re-arranging lines of text such as this one. – Chris Jun 13 '12 at 13:44
  • Maybe you could download the `sed` and `awk` versions from UnxUtils project and use them in your batch file. – adarshr Jun 13 '12 at 13:46

1 Answers1

2

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.

Community
  • 1
  • 1
Eitan T
  • 32,660
  • 14
  • 72
  • 109
  • ok but that will change for all variables FILE_NAME & FILE_SIZE but I want to do for 1 of them – Leo92 Jun 14 '12 at 11:56
  • @user1447199 - You shouldn't change your question completely, better ask a new one. It's a big difference, if it's XML, CSV or custom format – jeb Jun 14 '12 at 12:10
  • help plz , I noticed that there is a problem if the input file name has spaces in this line for /f "tokens=*" %%s in (%INPUT_FILE%) do call :ParseLine "%%s" , I tried to put "%INPUT_FILE%" but it didn't work , is there a solution ? – Leo92 Jun 28 '12 at 11:18
  • I found a valid solution , i made a swap like this , set input2="%INPUT_FILE%" and then : for /f "tokens=*" %%s in (%input2%) do call :ParseLine "%%s" and it worked , but maybe there is a smarter solution – Leo92 Jun 28 '12 at 13:15
  • I have a question , is it possible to use a word instead of `=` as a delimiter – Leo92 Jul 02 '12 at 14:22
  • @Leo92, no it's not possible, you'll have to use another trick to achieve that. – Eitan T Jul 02 '12 at 20:37