我正在尝试将易趣文件交换下载转换为制作软件可以阅读的制表符分隔格式。
如果引用每一列,这很容易 - 但它们不是。仅引用了一些列(名称,项目列表标题等),并且一些引用的列包含逗号。其余的都没有引用。
我需要一种在.bat文件中解析和转换它的方法,但是如果它们也包含逗号,则使用逗号作为分隔符会分割引用的字段,从而为我提供不可用的数据。我确定有一个简单的解决办法,我无法理解。
答案 0 :(得分:2)
主要问题是如何区分引用和不引用的逗号 - 在'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell,jeb解决了带引号与不带引号的分号的类似问题。下面的代码看起来非常不同,但基本概念是相同的。
只要所有行长度小于~8000字节,下面的代码几乎适用于任何CSV。批处理变量值限制为8191个字节,某些字符暂时扩展为两个字节。
代码假定CSV文件中没有任何现有的TAB。
它不会修改任何现有的引号。
正如我所说,代码应该可以工作,但是如果你有一个大文件,它会很痛苦。正如Eric J建议的那样,使用.NET解决方案会好得多。
@echo off
setlocal disableDelayedExpansion
set "file=optionalPathinfo\yourFile.csv"
:: Define a TAB variable
for /f "delims=" %%A in (
'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"'
) do set "TAB=%%A"
:: Read each line from CSV, convert it, and write to new file with .new extension
>"%file%.new" (
for /f usebackq^ delims^=^ eol^= %%A in ("%file%") do (
set "line=%%A"
call :processLine
)
)
exit /b
:processLine
setlocal enableDelayedExpansion
:: Protect problem characters
set "line=!line:@=@A!"
set "line=!line:^=@K!"
set "line=!line:&=@M!"
set "line=!line:|=@P!"
set "line=!line:<=@L!"
set "line=!line:>=@G!"
:: Mark commas with leading caret (escape)
set "line=!line:,=^,!"
:: Remove mark from unquoted commas, but first temporarily
:: disable delayed expansion to protect any ! characters
setlocal disableDelayedExpansion
set ^"line=%line%"
setlocal enableDelayedExpansion
:: Protect remaining marked commas
set "line=!line:^,=@C!"
:: Convert remaining commas to TAB
set "line=!line:,=%TAB%!"
:: Restore protected characters
set "line=!line:@C=,!"
set "line=!line:@G=>!"
set "line=!line:@L=<!"
set "line=!line:@P=|!"
set "line=!line:@M=&!"
set "line=!line:@K=^!"
set "line=!line:@A=@!"
:: Write modified line
echo(!line!
exit /b
答案 1 :(得分:1)
还有一个复杂的问题:带引号和逗号的字段也会有报价转义:
Jim“Smitty”Smith,Jr。
将在CSV文件中表示为
“Jim”“Smitty”“Smith,Jr。”
这不是批处理文件中容易解决的问题。但是,存在预先存在的功能来处理可以从任何.NET兼容语言(包括Powershell)使用的CSV格式。如果这是一个选项,请看看
http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
有关调用.NET方法从Powershell读取CSV文件的信息,请查看