Question : How to read a CSV using Windows Command Line

For a bassicly file oriented application I have to write some procedures. One of them reads a csv file and writes two other files based upon the information in the first file.
De contence of the input file is like:

#,6/29/2010,,,
222857293,2857293,V.E.C. Klanta,en/of V.E.C. Klantc,3
223509302,3509302,V.E.C.Klantb,,9

The FOR command I'm using is having trouble with the empty field (fourth) in the last line. The write action (echo in the snippet) is done depending on the 3 or the 9 in the last field. Now field 4 is empty field 4 will get the value of field 5.
Is there a way to prevent this beheavior of the FOR command?

Thanks in advanced!
John
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
:: Creating custodian group
::  9 = KB
::  3 = ABN
:: ******************************************************
:create_custodian_group
  
  FOR /F "skip=1 tokens=1,2,3,4,5 delims=," %%G in (%a_vanvec%vecacc.csv) do (
    call :s_write_group %%G %%H "%%I" "%%J" %%K)
  GOTO :einde
  
:s_write_group

if not [%5]==[3] (
  if not [%5]==[9] (
    echo 1=%1 2=%2 3=%3 4=%4 5=%5 wrong code
  ) else (
    echo KB = %1 - %5
  )
) else echo abn = %1 - %5

:: end of subroutine
  GOTO :eof

:einde
pause

Answer : How to read a CSV using Windows Command Line

There isn't any way to tell the FOR command not to treat consecutive delims as a single delim.  The way I typically work around this is to "pre process" the input line and look for pairs of delims with nothing between them.  I replace these with something in between the delims that I can then check for in the code and treat as a missing or empty value.

So if the input line was

aaa,,,bbb

And I want to process 4 values rather than the 2 that the FOR will pickup by default, then I first convert the line to

aaa,@,@,bbb

and then feed that into the FOR and parse on comma.

I'm attaching the code with this change, let me know how it goes for you.  I made a couple of other small adjustments, let me know what questions you have.

- needed to add the setlocal EnableDelayedExpansion so that I could update and use a variable inside a loop

- defined the input file name as a variable, and quoted it in the main FOR that reads it, to handle the case where the filename could include spaces

- the outer FOR loop reads the entire line, then we assign that to a variable so that we can replace the "empty" values with a placeholder (I used @, could be anything you like)

- then another FOR much like your original one parses the resultant string and calls the subroutine

- I added an ECHO of the inputline before and after the conversion just so you can see how it works, these would be removed later

Hope this helps

~bp
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
@echo off
setlocal EnableDelayedExpansion
 
REM Creating custodian group
REM  9 = KB
REM  3 = ABN
REM ******************************************************
set InputFile=%a_vanvec%vecacc.csv
 
:create_custodian_group
  
for /F "usebackq skip=1 tokens=*" %%A in ("%InputFile%") do (
  set InputLine=%%A
  echo BEFORE: !InputLine!
  for /L %%B in (1,1,20) do (
    set InputLine=!InputLine:,,=,@,!
  )
  echo AFTER : !InputLine!
  for /F "tokens=1-5 delims=," %%G in ("!InputLine!") do (
    call :s_write_group %%G %%H "%%I" "%%J" %%K
  )
)
GOTO :einde
  
:s_write_group
  if not [%5]==[3] (
    if not [%5]==[9] (
      echo 1=%1 2=%2 3=%3 4=%4 5=%5 wrong code
    ) else (
      echo KB = %1 - %5
    )
  ) else (
    echo abn = %1 - %5
  )
 
  REM end of subroutine
  GOTO :eof
 
:einde
  pause
Random Solutions  
 
programming4us programming4us