批处理脚本 – Txt到CSV,如何将文本限定符添加到列?

我试图让这个脚本自动将文本文件转换为CSV文件,但是由pipe道字符“|”分隔。 我在下面的是在我的batch file中,它用逗号replacepipe道,我唯一的问题是,在第七列中,string包含逗号,所以当我在Excel中打开CSV文件时,它将这些逗号视为列并混淆列的格式。 有没有办法只添加文本限定符到第7列? 文本限定符在string周围引号。

值1 |值2,AndSome |值3

让脚本将文本文件转换为:

值1, “值2,AndSome”,值3

@echo off setLocal enableDELAYedexpansion for /f "tokens=* delims=^|" %%a in (myFile.txt) do ( set str=%%a echo !str:^|=,! >> myFile.csv ) 

 @ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION SET "sourcedir=U:\sourcedir" SET "filename1=%sourcedir%\q35002863.txt" FOR /f "usebackqtokens=1-7*delims=^|" %%a IN ("%filename1%") DO ( SET "C8=%%h" ECHO(%%a,%%b,%%c,%%d,%%e,%%f,"%%g",!C8:^|=,! ) GOTO :EOF 

这应该可以解决你的问题。

JREPL.BAT是一个function强大的正则expression式查找/replace工具,可以轻松有效地解决这个问题。 这是纯粹的脚本(混合JScript /批处理),从XP以后的任何Windows机器上本机运行。

我可以写一个总是引用第7列的解决scheme,但是这个方法的使用有限。 更强大的将是一个解决scheme,有select地引用任何包含逗号的列,而不pipe位置。 任何没有逗号的列将保持不加引号。

 jrepl "\| [^|,]*,[^|]*" ", \q$&\q" /t " " /x /f myFile.txt /o myFile.csv 

除此之外,唯一可能引发你意外的是任何一列已经包含一个引号。 CSV“标准”要求任何引号字面都要转义为"" ,并且该字段也用引号引起来。 以下内容将正确地转义引用字面值,并附上引号内包含逗号或引号的任何列。

 jrepl "\| [^|,]*[,\x22][^|]*" "',' '\x22'+$0.replace(/\x22/g,'\x22\x22')+'\x22'" /t " " /j /f myFile.txt /o myFile.out 

可以添加的最后一件事情是将该命令放在批处理脚本中,然后参数化分隔符,源文件和目标文件。 我还为脚本添加了一个帮助工具。

delim2csv.bat

 :: ::delim2csv Delimiter InFile [OutFile] ::delim2csv /? :: :: Convert a delimited text file into a CSV file, where :: - columns containing comma or quote are quoted :: - quote literals are doubled :: - Delimiter characters are converted to commas :: :: The OutFile is optional. The result will be written to stdout :: if the OutFile is not specified. Use - for the OutFile to :: overwrite the InFile with the result. :: :: Remember that the delimiter is used in a regular expression, :: so the character must be escaped if it is a regex meta character, :: or encoded if it is difficult to represent on the command line. :: Any extended ASCII character may be specified by using \xNN, :: where NN is the hexidecimal representation of the character code. :: Enclosing argument quotes will be removed before use in the regex. :: :: Example Delimiters: pipe = "\|" or \x7C :: tab = \t or \x09 :: :: If the first argument is /?, then this help documentation will :: be written to stdout. :: :: This script requires JREPL.BAT to function, available at: :: http://www.dostips.com/forum/viewtopic.php?t=6044 :: @echo off if "%~1" equ "/?" ( for /f "delims=: tokens=1*" %%A in ('findstr /n "^::" "%~f0"') do echo(%%B exit /b ) @call jrepl "%~1 [^%~1,]*[,\x22][^%~1]*"^ "',' '\x22'+$0.replace(/\x22/g,'\x22\x22')+'\x22'"^ /t " " /j /f %2 /o %3 

所以,使用上面的脚本,解决scheme将变成:

 delim2csv "\|" MyFile.txt MyFile.csv 

编辑2017-02-19

Over at https://stackoverflow.com/a/42324094/1012053我开发了一个名为parseCSV.bat的小型混合脚本,专门用于转换CSV数据,并且不使用正则expression式。 它比依赖JREPL.BAT的上述解决scheme快11倍以上。 正则expression式强大,方便,简洁,但手工构build的代码通常更快。

随着parseCSV.bat,解决scheme成为

 parseCSV "/I:|" /L /Q:E <MyFile.txt >MyFile.csv 

输出中的唯一区别是parseCSV会引用每个列值,但delim2csv只会引用包含逗号或引号的列值。