循环通过CSV文件与批行解决问题

这是对另一个问题的扩展( 通过批量循环CSV文件 – 空间问题 )

我有这样的csv文件内容

name,sex,age,description,date venu,m,16,test mesg,2012-05-01 test,f,22,"He is good guy and brilliant",2012-05-01 

我使用这个命令循环这个文件。

 For /F "usebackq tokens=1-3 delims=" %%x in (test.csv) Do ( 

但是由于第二行存在换行符,即使文件中有两条logging,我也得到3条logging。

如何解决这个问题? 提前致谢。

Solutions Collecting From Web of "循环通过CSV文件与批行解决问题"

主要的问题似乎是在一行中计算报价。
如果报价计数是奇数,那么您需要追加下一行并重新计算报价。

计算字符串中的字符是有点棘手的,如果你不会遍历所有的字符。
我在这里使用延迟减少技术,每个报价将有效地取代一个+1和所有其他字符被删除。
以合适的方式开始和终止线路,始终总是有一个额外的+1 ,这将在前面用-1来补偿。

主要的诀窍是用一个+1代替完整的文本从一个报价到下一个报价,用!!#:#=替换每个报价。
这可以作为!#:#=...<some text>...! 将始终扩展到+1 ,因为变量#的内容是+1 ,所以搜索模式#不能被找到。
其他替换只是为了避免文本中出现感叹号和插入符号的问题。

 ::::::::::::::::::::::::::::::::::::::::::: :CountQuotes <stringVar> <result> setlocal EnableDelayedExpansion set "line=!%~1!" set "#=+1" rem DelayedExpansion: double all quotes set "line=!line:"=""!" rem DelayedExpansion: remove all carets ^ set "line=!line:^=!" rem PercentExpansion: Remove all ! set "line=%line:!=%" rem PercentExpansion: Replace double quotes to !!#:#= set "line=-1^!#:#=%line:""=^!^!#:#=%" for /F "delims=" %%X in ("!line!") do ( set /a count=%%X! ) ( endlocal set %~2=%count% exit /b ) 

以及添加行和插入换行符的逻辑

 @echo off setlocal DisableDelayedExpansion set "lastLine=" set LF=^ rem Two empty lines for /F "delims=" %%A in (test.csv) do ( set "line=%%A" setlocal EnableDelayedExpansion set "line=!line:\=\x!" if defined lastLine ( set "line=!lastLine!\n!line!" ) call :CountQuotes line quoteCnt set /a rest=quoteCnt %% 2 if !rest! == 0 ( for %%L in ("!LF!") DO set "line=!line:\n=%%~L!" set "line=!line:\\=\!" echo Complete Row: !Line! echo( set "lastLine=" ) ELSE ( set "lastLine=!line!" ) for /F "delims=" %%X in (""!lastLine!"") DO ( endlocal set "lastLine=%%~X" ) ) exit /b ::::::::::::::::::::::::::::::::::::::::::: :CountQuotes <stringVar> <result> setlocal EnableDelayedExpansion set "line=!%~1!" set "#=+1" rem DelayedExpansion: double all quotes set "line=!line:"=""!" rem DelayedExpansion: remove all carets ^ set "line=!line:^=!" rem PercentExpansion: Remove all ! set "line=%line:!=%" rem PercentExpansion: Replace double quotes to !!#:#= set "line=-1^!#:#=%line:""=^!^!#:#=%" for /F "delims=" %%X in ("!line!") do ( set /a count=%%X! ) ( endlocal set %~2=%count% exit /b ) 

下面的批处理文件做你想要的:

 @echo Off setlocal EnableDelayedExpansion call :processFile < test.csv goto :EOF :processFile set line= set /P line= if not defined line exit /b set "line=!line:,,=,@,!" for %%a in (name sex age description mydate) do set %%a= for %%a in (!line!) do ( if not defined name ( set "name=%%a" ) else if not defined sex ( set "sex=%%a" ) else if not defined age ( set "age=%%a" ) else if not defined description ( set "description=%%a" ) else if not defined mydate ( set "mydate=%%a" ) ) :checkDate if defined mydate goto show set /P line= for /F "tokens=1* delims=," %%a in ("!line!") do ( set "description=!description! %%a" set "mydate=%%b" ) goto checkDate :show for %%a in (name sex age description mydate) do set /P "=%%a=!%%a!, " < NUL echo/ goto processFile 

我在你之前的主题中添加了你所要求的要求,也就是说,性别可能是空的(如我在该主题的回答中所解释的那样,由@字符改变),并且该名称可以包括逗号。 我用这个数据文件测试了程序:

 name,sex,age,description,date venu,m,16,"test mesg",2012-05-01 test,,22,"He is good guy and brilliant",2012-05-01 "venu,gopal",m,16,"Another multi-line description",2012-05-02 

并得到这些结果:

 name=name, sex=sex, age=age, description=description, mydate=date, name=venu, sex=m, age=16, description="test mesg", mydate=2012-05-01, name=test, sex=@, age=22, description="He is good guy and brilliant", mydate=2012-05-01, name="venu,gopal", sex=m, age=16, description="Another multi-line description", mydate=2012-05-02, 

请注意,任何包含逗号或空格的字段都必须用引号引起来。