Assuming you already have a representative line in a variable, then the following pure batch can reliably determine the number of fields, provided that no field contains a newline character. The Microsoft spec for CSV allows for newlines in fields, but they are rare, and the issue can probably be disregarded.
The code allows for any other character in a field, and accounts for quoted comma literals in fields, as well as doubled quotes representing a quote literal.
The algorithm is a derivative of a technique used by jeb to properly parse paths within the PATH variable. In that case the ;
is a delimiter, but quoted paths can contain ;
literals.
@echo off
setlocal
set "line=,,<&^|>!,,1,2,,,"4,^<^&^^^|^>!0",5,"a,""b"",c",,"
set line
setlocal enableDelayedExpansion
:: Remove all poison characters
if defined line set "line=!line:^=!"
if defined line set "line=!line:<=!"
if defined line set "line=!line:>=!"
if defined line set "line=!line:|=!"
if defined line set "line=!line:&=!"
:: Remove all !
if defined line set "line=%line:!=%"
:: Convert all true , delimiters to ^, - Note the enclosing quotes cause delimiters to be quoted
:: The , in values are also converted, but they are no longer quoted so they revert back to ,
if defined line set "line=%line:,=^,%"
:: Convert ^, delimiters into newline
for %%N in (^"^
%= This creates a quoted newline character =%
^") do if defined line set "line=!line:^,=%%~N!"
:: Count the number of lines in string and save result
setlocal disableDelayedExpansion
for /f %%N in ('cmd /v on /c echo(!line!^|find /c /v ""') do set "cnt=%%N"
echo %cnt% fields
-- OUTPUT --
line=,,<&^|>!,,1,2,,,"4,<&^|>!0",5,"a,""b"",c",,
13 fields