Search code examples
windowscsvfor-loopbatch-filecmd

How can I count the number of tokens generated by a for /f loop?


Very sorry if this has been asked and answered already. I have looked through similarly-titled questions without finding one that seemed applicable to me. Also, this is my first question posted on Stack Overflow.

I have a csv file called sortcriteria.csv that currently consists of 12 columns and 5 rows.

Here is the csv file's content:

Private,ReadWriteInc,TheArts,Preschool,Transition,Staff,Music,Language,MultiYearOrGroups,MiddleYears,PhysicalActivity,StudentLeaders
PLT,RWI,Art,Pre,Tran,Staff,Uke,Language,Group,MiddleYears,PhysicalActivity,StudentLeaders
Personal,",",",",",Ukulele,Japanese,",",PE,"
Private,",",",",",Guitar,German,",",","
11 ,",",",",",Music,",",",","

Here is a picture of the csv in Excel: picture of csv in Excel

If I were to run this through a for /f loop with the delimiter set to comma, I could get 12 tokens, one for each column. For example, the following code would generate 12 variables:

for /f "delims=, tokens=1-12" %%B in (C:\GAMWork\sortcriteria.csv) do ...

For sortcriteria.csv in its current form, this for loop would iterate 5 times (once for each line) with each time generating 12 variables (%%B through to %%M). It will do this because I have told it that there are 12 columns, or tokens, with "tokens=1-12".

However, the csv file may not always have 12 columns. Columns may be added or subtracted in the future. How can I get the batch file to first count the number of columns in the csv file and then use that number to determine how many tokens the for /f loop looks for?

I am hoping for something like the following:

<some code block that counts the number of columns in the csv file>

set /a tknnum=<Result from code block above>

for /f "delims=, tokens=1-%tknnum%" %%B in (C:\GAMWork\sortcriteria.csv) do ...

I'm especially hoping that I can set the number of columns to the tknnum variable, as I also need to use it elsewhere in the batch file for another purpose.

I hope this explanation is clear and understandable.

I do not have any examples of things that I have tried, as I don't really know where to start to attempt a solution. I cannot think of a way to process the csv file using for /f that will count the number of columns. I have read the documentation for the for command from Microsoft's website, as well as from ss64.com. As mentioned, I have also searched other question here on Stack Overflow with similar titles. Of those I could understand, none seemed applicable in my context. The closest I could find is this one: https://stackoverflow.com/a/72903742/, however I got lost trying to understand @Magoo's answer.

EDIT: I realise that using " as a filler for blank cells is a bad idea. Sorry.


Solution

  • To answer your question so far:
    get the number of columns (use the first line, which is the header) by just counting the elements (Attention: this uses standard delimiters (not changeable), so if there should be spaces in a column, the value has to be quoted (like "Student Leaders".

    @echo off
    <sortcriteria.csv set /p header=
    set columns=0
    for %%a in (%header%) do set /a columns+=1
    echo Your file has %columns% columns.
    for /f "tokens=1-%columns% delims=," %%a in (sortcriteria.csv) do ...
    

    Still open question: you still don't know which letter is your last token. There might be a better solution. What exactly do you want to do?