Squashman 有一个好主意,使用我的parseCSV.bat utility 进行转换。该实用程序是一个使用批处理和 JScript 的混合脚本。此实用程序比任何纯批处理解决方案都快得多,并且它可以在 XP 以后的任何 Windows 机器上本地运行 - 不需要 3rd 方 exe。
该实用程序实际上是为了允许在批处理文件中通过 FOR /F 方便地解析 CSV 文件。版本 1.0 有一个问题,这使得它不太适合使用该实用程序来转换 CSV 格式以供其他用途 - 转义的引号文字未转义,因此 "" 变为 "。这种转换对于 FOR /F 解析很有用,但它不是有效的 CSV 格式。
我修改了该实用程序,使其具有保留引号文字转义的选项。现在您可以安全地使用以下命令将分号快速转换为逗号分隔符。
parseCSV /I:; /Q:E <input.csv >output.csv
因为 parseCSV 本身就是一个批处理脚本,所以如果您在另一个批处理脚本中使用该命令,则必须使用 call parseCSV。
我能够在 2.5 分钟内使用 parseCSV.bat 转换一个 53MB 的文件。
这是 parseCSV 的代码。但是,我不承诺保持此代码为最新。我建议您从DosTips post 获取代码。您还可以在此处找到该实用程序其他功能的详细说明。
@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment
::************ Documentation ***********
::parseCSV.bat version 1.2
:::
:::parseCSV [/option]...
:::
::: Parse stdin as CSV and write it to stdout in a way that can be safely
::: parsed by FOR /F. All columns will be enclosed by quotes so that empty
::: columns may be preserved. It also supports delimiters, newlines, and
::: escaped quotes within quoted values. Two consecutive quotes within a
::: quoted value are converted into one quote by default.
:::
::: Available options:
:::
::: /I:string = Input delimiter. Default is a comma (,)
:::
::: /O:string = Output delimiter. Default is a comma (,)
:::
::: The entire option must be quoted if specifying poison character
::: or whitespace literals as a delimiters for /I or /O.
:::
::: Examples: pipe = "/I:|"
::: space = "/I: "
:::
::: Standard JScript escape sequences can also be used.
:::
::: Examples: tab = /I:\t or /I:\x09
::: backslash = /I:\\
:::
::: /E = Encode output delimiter literal within value as \D
::: Encode newline within value as \N
::: Encode backslash within value as \S
:::
::: /D = escape exclamation point and caret for Delayed expansion
::: ! becomes ^!
::: ^ becomes ^^
:::
::: /L = treat all input quotes as quote Literals
:::
::: /Q:QuoteOutputFormat
:::
::: Controls output of Quotes, where QuoteOutputFormat may be any
::: one of the following:
:::
::: L = all columns quoted, quote Literals output as " (Default)
::: E = all columns quoted, quote literals Escaped as ""
::: N = No columns quoted, quote literals output as "
:::
::: The /Q:E and /Q:N options are useful for transforming data for
::: purposes other than parsing by FOR /F
:::
::: /U = Write unix style lines with newline (\n) instead of the default
::: Windows style of carriage return and linefeed (\r\n).
:::
:::parseCSV /?
:::
::: Display this help
:::
:::parseCSV /V
:::
::: Display the version of parseCSV.bat
:::
:::parseCSV.bat was written by Dave Benham. Updates are available at the original
:::posting site: http://www.dostips.com/forum/viewtopic.php?f=3&t=5702
:::
::************ Batch portion ***********
@echo off
if "%~1" equ "/?" (
setlocal disableDelayedExpansion
for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do echo(%%A
exit /b 0
)
if /i "%~1" equ "/V" (
for /f "delims=:" %%A in ('findstr /bc:"::%~nx0 version " "%~f0"') do echo %%A
exit /b 0
)
cscript //E:JScript //nologo "%~f0" %*
exit /b 0
************ JScript portion ***********/
var args = WScript.Arguments.Named,
stdin = WScript.Stdin,
stdout = WScript.Stdout,
escape = args.Exists("E"),
literalQ = args.Exists("L"),
escapeQ = (args.Item("Q")&&args.Item("Q").toUpperCase()=="E"),
quoteCol = (args.Item("Q")&&args.Item("Q").toUpperCase()=="N") ? '' : '"',
delayed = args.Exists("D"),
inDelim = args.Item("I") ? eval('"'+args.Item("I")+'"') : ",",
outDelim = args.Item("O") ? eval('"'+args.Item("O")+'"') : ",",
newline = args.Exists("U") ? "\n" : "\r\n",
quote = false,
ln, c, n, out;
while (!stdin.AtEndOfStream) {
ln=stdin.ReadLine();
out="";
if (!quote) stdout.Write(quoteCol);
for (n=0; n<ln.length; n++ ) {
c=ln.charAt(n);
if (c == '"') {
if (literalQ) {
if (escapeQ) c+='"';
} else if (quote && ln.charAt(n+1) == '"') {
n++;
if (escapeQ) c+='"';
} else {
quote=!quote;
continue;
}
}
else if (c == inDelim && !quote) c=quoteCol+outDelim+quoteCol;
else if (escape) {
if (c == outDelim) c="\\D";
if (c == "\\") c="\\S";
}
else if (delayed) {
if (c == "!") c="^!";
if (c == "^") c="^^";
}
out+=c;
}
out += (quote) ? ((escape) ? "\\N" : newline) : quoteCol+newline;
stdout.Write(out);
}