JREPL.BAT 是一个功能强大的正则表达式查找/替换实用程序,可以轻松有效地解决此问题。它是纯脚本(混合 JScript/batch),可以在 XP 以后的任何 Windows 机器上本地运行。
我可以编写一个始终引用第 7 列的解决方案,但它的用途有限。更强大的解决方案是选择性地引用任何包含逗号的列,而不管位置如何。任何没有逗号的列都不会被引用。
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
因此,使用上述脚本,解决方案将变为:
delim2csv "\|" MyFile.txt MyFile.csv
编辑 2017-02-19
在https://stackoverflow.com/a/42324094/1012053,我开发了一个名为 parseCSV.bat 的小型混合脚本,专门用于转换 CSV 数据,并且不使用正则表达式。它比上述依赖 JREPL.BAT 的解决方案快 11 倍以上。正则表达式功能强大、方便且简洁,但手动构建的代码通常更快。
有了parseCSV.bat,解决方案就变成了
parseCSV "/I:|" /L /Q:E <MyFile.txt >MyFile.csv
输出的唯一区别是 parseCSV 引用每个列值,但 delim2csv 仅引用包含逗号或引号的列值。