结合2个csv文件的新CSV

时间:2017-01-19 00:28:47

标签: batch-file cmd

我有2个CSV文件

File1中:

Column1,column2
data1, data2

文件2:

Column3,column4, column5,column6
data3,data4,data5,data6

我必须创建一个新的CSV文件,它将文件1中的列与文件2中的第1列和第3列(总共4列)组合在一起。

Column1,column2,column3,column5
data1,data2,data3,data5

我希望使用批处理文件命令来执行此操作。有什么建议?

我正在使用的代码帮助我复制一个文件。

@ECHO OFF
SETLOCAL
(
FOR /f "tokens=1-3delims=," %%a IN (file1.csv) DO (
 ECHO(%%a,%%c
)
)>new.csv

GOTO :EOF

3 个答案:

答案 0 :(得分:0)

如何关注以下脚本?

File1.csv:

column1,column2
data1,data2
data3,data4
data5,data6

File2.csv:

column3,column4,column5,column6
data3,data4,data5,data6
data7,data8,data9,data10

脚本:

@echo off
setlocal enabledelayedexpansion

set ct1=0
for /f "tokens=*" %%i in (File1.csv) do (
    set /a ct1+=1
    set ar1[!ct1!]=%%i
)

set ct2=0
for /f "tokens=*" %%i in (File2.csv) do (
    set /a ct2+=1
    set ar2[!ct2!]=%%i
)

if !ct1! lss !ct2! (
    set ct=!ct2!
) else (
    set ct=!ct1!
)

for /l %%i in (1,1,!ct!) do (
    echo !ar1[%%i]!,!ar2[%%i]!>> new.csv
)

new.csv:

column1,column2,column3,column4,column5,column6
data1,data2,data3,data4,data5,data6
data3,data4,data7,data8,data9,data10
data5,data6,

答案 1 :(得分:0)

这是一个有效的纯批处理解决方案,但有以下限制和/或假设:

  • 文件1行以回车符和换行符(Windows样式)终止
  • 文件1行不超过1021字节
  • 文件2必须具有每列的值(没有连续的逗号)
  • 文件2行长度不超过~8191字节
  • 文件2没有任何包含逗号的引用列值。
  • 文件1和2具有相同的行数
  • 这两个文件都没有引用包含新行的数据值(很少见,但可能在CSV中)。
@echo off
setlocal disableDelayedExpansion
<"file1.csv" >"merged.csv" (
  for /f "usebackq eol=, delims=, tokens=1,3" %%A in ("file2.csv") do (
    set /p "part1="
    set "part2=%%A,%%B"
    setlocal enableDelayedExpansion
    echo !part1!,!part2!
    endlocal
  )
)

如果您使用PowerShell,JScript或VBS,则可以使用更强大,更快速的解决方案。

您还可以使用JREPL.BAT - a regular expression text processing utility实施高效且强大的解决方案。 JREPL.BAT是纯脚本(混合批处理/ JScript),可以在XP之后的任何Windows机器上本机运行。可以从命令行通过jrepl /?jrepl /??获取完整文档以获取分页帮助。

此JREPL解决方案仅具有以下合理限制:

  • 文件1和2必须具有相同的行数
  • 两个文件都没有引用包含新行的数据值
@echo off
setlocal
set "col=\q(?:\q\q|[^,\q])*\q|[^,]*"
call jrepl "^(%col%),(?:%col%),(%col%)(?:,.*|$)" ^
           "$txt=stdin.ReadLine()+','+$1+','+$2" ^
           /jq /x /f "file2.csv" /o "merged.csv" <"file1.csv"

答案 2 :(得分:0)

这个灵活的脚本可以满足您的需求,因为不会违反以下限制:

  • 两个文件必须包含相同数量的行;
  • 每行/每行的列数必须相等;
  • 行不超过1023个字节,包括终止换行符;
  • 字段/单元格值不得包含换行符;
  • 每个行/行必须由Windows样式的换行符(CR + LF)终止;
  • 要复制的给定列号必须按升序排序;

所以这是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE1=%~dp0File1.csv" & rem // (1st input CSV file; state `%~1` to use 1st arg.)
set "_FILE2=%~dp0File2.csv" & rem // (2nd input CSV file; state `%~2` to use 2nd arg.)
set "_COLS1=1,2"            & rem // (ascending list of columns to copy from 1st file)
set "_COLS2=1,3"            & rem // (ascending list of columns to copy from 2nd file)
set "_SEPAR=,"              & rem // (separator character, usually `,`)

rem // Main routine:
4< "%_FILE1%" 3< "%_FILE2%" (
    call :READLINE
)

endlocal
exit /B


:READLINE
    rem // Read a line of both files:
    set "LINE1=" & set "LINE2="
    <&4 set /P LINE1=""
    <&3 set /P LINE2=""
    rem // Terminate sub-routine in case both lines are empty:
    if not defined LINE1 if not defined LINE2 exit /B
    rem // Process lines:
    call :PROCESS LINE1 LINE2
    rem // Repeat reading:
    goto :READLINE
    exit /B


:PROCESS  ref_string1  ref_string2
    setlocal DisableDelayedExpansion
    set "BUF=%_SEPAR%"
    setlocal EnableDelayedExpansion
    rem // Test both strings against global wild-card characters:
    set "STR1=!%~1!" & set "STR2=!%~2!"
    if "!STR1:**=!!STR2:**=!"=="!STR1!!STR2!" goto :PROCESS_CONT
    if "!STR1:*?=!!STR2:*?=!"=="!STR1!!STR2!" goto :PROCESS_CONT
    if "!STR1:*<=!!STR2:*<=!"=="!STR1!!STR2!" goto :PROCESS_CONT
    if "!STR1:*>=!!STR2:*>=!"=="!STR1!!STR2!" goto :PROCESS_CONT
    >&2 echo(ERROR: Illegal character encountered^^!
    exit /B 1
    :PROCESS_CONT
    rem // Prepare line strings for being processed by a standard `for` loop:
    set "STR1=!STR1:"=""!^"
    set "STR2=!STR2:"=""!^"
    set "STR1="!STR1:%_SEPAR%=","!""
    set "STR2="!STR2:%_SEPAR%=","!""
    rem // `for /F` loops to transport prepared line strings beyond `endlocal`:
    for /F "delims=" %%E in (^""!STR1!"^") do (
        for /F "delims=" %%F in (^""!STR2!"^") do (
            endlocal
            rem // Process 1st line string:
            set /A "IDX=0"
            for %%I in (%%~E) do (
                rem // Compare column index of current item with given column list:
                set /A "IDX+=1" & set "FND="
                for %%J in (%_COLS1%) do (
                    setlocal EnableDelayedExpansion
                    if !IDX! EQU %%J (
                        endlocal & set "FND=#"
                    ) else endlocal
                )
                rem // Matching column index encountered, so assemble output line:
                if defined FND (
                    set "NEW=%%~I%_SEPAR%"
                    setlocal EnableDelayedExpansion
                    for /F "delims=" %%K in (^""!BUF!!NEW!"^") do (
                        endlocal
                        set "BUF=%%~K"
                    )
                )
            )
            rem // Process 1st line string:
            set /A "IDX=0"
            for %%I in (%%~F) do (
                rem // Compare column index of current item with given column list:
                set /A "IDX+=1" & set "FND="
                for %%J in (%_COLS2%) do (
                    setlocal EnableDelayedExpansion
                    if !IDX! EQU %%J (
                        endlocal & set "FND=#"
                    ) else endlocal
                )
                rem // Matching column index encountered, so assemble output line:
                if defined FND (
                    set "NEW=%%~I%_SEPAR%"
                    setlocal EnableDelayedExpansion
                    for /F "delims=" %%K in (^""!BUF!!NEW!"^") do (
                        endlocal
                        set "BUF=%%~K"
                    )
                )
            )
            setlocal EnableDelayedExpansion
        )
    )
    rem // Return output line buffer:
    echo(!BUF:~1,-1!
    endlocal
    endlocal
    exit /B