如何根据带有标题的列值(不使用AWK)将CSV文件拆分为多个文件

时间:2016-08-18 06:08:31

标签: csv batch-file

我有一张包含发票数据的CSV - 例如:
•发票#
•PO参考
•客户代码
•客户名称
•文件日期
•产品代码
•产品名称

此CSV将包含每张发票不同的行数,这些行与发票产品行相关,可能跨越多个发票号。

我需要能够运行批处理文件来查看此CSV,并根据Col A - Invoice中的值拆分成多个CSV,并在文件中生成带有标题的每个文件。

例如:

Invoice,PORef,CustomerCode,CustomerName,DocumentDate,ProductCode,ProductName
111222,PO123,C100000,Test Store,1/1/15,AB1000,Test Soft Toy
111222,PO123,C100000,Test Store,1/1/15,AB1001,Test Soft Toy1
111222,PO123,C100000,Test Store,1/1/15,AB1002,Test Soft Toy2
222111,PO321,C111000,My Store,1/10/15,AB1000,Test Soft Toy
222111,PO321,C111000,My Store,1/10/15,AB1001,Test Soft Toy1
222111,PO321,C111000,My Store,1/10/15,AB1002,Test Soft Toy2

.bat应该运行并将CSV拆分为2个单独的CSV:

CSV1:

Invoice,PORef,CustomerCode,CustomerName,DocumentDate,ProductCode,ProductName
111222,PO123,C100000,Test Store,1/1/15,AB1000,Test Soft Toy
111222,PO123,C100000,Test Store,1/1/15,AB1001,Test Soft Toy1
111222,PO123,C100000,Test Store,1/1/15,AB1002,Test Soft Toy2

CSV2:

Invoice,PORef,CustomerCode,CustomerName,DocumentDate,ProductCode,ProductName
222111,PO321,C111000,My Store,1/10/15,AB1000,Test Soft Toy
222111,PO321,C111000,My Store,1/10/15,AB1001,Test Soft Toy1
222111,PO321,C111000,My Store,1/10/15,AB1002,Test Soft Toy2

在我的服务器上安装软件会很麻烦 - 因此,如果无论如何都可以在不安装软件的情况下完成,这将使我非常高兴。

我很欣赏以前提出的类似问题 - 但是,我无法确定是否有其他脚本可以在不安装Awk的情况下运行。

关心Amol Murkute

2 个答案:

答案 0 :(得分:1)

实际上,批处理很容易:

@echo off
set file=full.csv

REM get header:
<full.csv set /p header=

REM process file line by line (ignore header):
for /f "skip=1 tokens=1,* delims=," %%a in (%file%) do (
  if not exist "%%a.csv" echo %header%>"%%a.csv"
  echo %%a,%%b>>"%%a.csv"
)

将每一行拆分为两个令牌(Invoice和&#34; rest-of-line&#34;)。作为拆分文件的名称,您可以使用发票编号。

答案 1 :(得分:0)

正确解析CSV数据在批处理脚本中并不是那么简单,所以我决定提供一个解决方案,尽管您没有展示任何自己的研究,也没有分享任何努力。

假设您的CSV文件不包含任何全局通配符?*,则以下代码段可能适用于您(提供CSV输入文件作为命令行参数):< / p>

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "FILE=%~f1"
set "FSEP=_"
set "DSEP=,"
set "DCOL=Invoice"
set /A "NCOL=0"

if not defined FILE set "FILE=%~dpn0.csv"
if not defined FSEP set "FSEP=_"
if not defined DSEP set "DSEP=,"
set /A "NCOL+=0"

for %%F in ("%FILE%") do (
    set "FLAG=#"
    2> nul del /Q "%%~dpnF%FSEP%*%%~xF"
    for /F usebackq^ delims^=^ eol^= %%L in ("%%~fF") do (
        set "LINE=%%L"
        set /A "CIDX=0"
        setlocal EnableDelayedExpansion
        rem Double " characters:
        set "LINE=!LINE:"=""!^"
        set "LINE="!LINE:%DSEP%=","!""
        if defined FLAG (
            if defined DCOL (
                for %%I in (!LINE!) do (
                    endlocal
                    set /A "CIDX+=1"
                    if /I "%%~I"=="%DCOL%" set /A "NCOL=CIDX"
                    setlocal EnableDelayedExpansion
                )
            )
            endlocal
            set "FLAG="
            set "HEAD=%%L"
            setlocal EnableDelayedExpansion
        ) else (
            set "NAME="
            for %%I in (!LINE!) do (
                endlocal
                set /A "CIDX+=1"
                setlocal EnableDelayedExpansion
                if !CIDX! EQU !NCOL! (
                    endlocal
                    set "NAME=%%~I"
                    setlocal EnableDelayedExpansion
                )
            )
            if defined NAME (
                if not exist "%%~dpnF%FSEP%!NAME!%%~xF" (
                    > "%%~dpnF%FSEP%!NAME!%%~xF" (echo(!HEAD!)
                )
                >> "%%~dpnF%FSEP%!NAME!%%~xF" (echo(!LINE!)
            )
        )
        endlocal
    )
)

endlocal
exit /B

生成的输出文件存储在输入文件的位置,并且命名为输入文件,并附加了依赖列的值(由_分隔)。

要考虑拆分文件的列可以由列(标题)名称由变量DCOL给出,或者(如果DCOL为空/未定义)由列号由变量NCOL

此脚本不使用for /F来获取字段(单元格)项,而是使用标准for循环,以免在引用的项目中遇到包含分隔符的问题。