【问题标题】:Cmd line CSV merge errorCmd 行 CSV 合并错误
【发布时间】:2017-04-02 14:31:30
【问题描述】:

我从命令行合并了许多 CSV 文件。但是,在 Excel 中打开生成的文件时,每个 CSV 的第一行会附加到前一个 CSV 的最后一行。我尝试了其他合并方式,但发生了同样的事情。

例如: 从我运行的命令行:

copy *.csv all.csv 

CSV #1 的第 56 行是 a,b,c

CSV #2 的第 1 行是 1,2,3

合并的 CSV 将是 a,b,c1,2,3

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: excel csv command-line merge


    【解决方案1】:

    下一个脚本展示了一些合并(实际上是附加)场景:

    • simple COPY:如果文件中的最后一行缺少标准行结尾,即 CRLF,则批准所描述的行连接;
    • loop COPY:修复了上述问题,但可以在输出文件中添加一些空行;
    • loop TYPE:同loop COPY;
    • loop ECHO:可能是允许处理的最佳解决方案,例如正确的 CSV 标题(如果存在);
    • 在simple COPY之前提前追加CRLF:和loop COPY一样,但是很简单,可以写成oneliner
      • del all.csv&(for %G in ( *.csv ) do @>>"%~G" echo()&copy *.csv all.csv /B

    请注意,copy *.csv all.csv 没有结尾 /B 开关可能会将 Ctrl+Z 字符放在 all.csv 结尾。

    脚本

    @ECHO OFF
    SETLOCAL EnableExtensions DisableDelayedExpansion
    
        REM change the current directory to a test folder 
    pushd d:\bat\files\folder
    
        REM create sample input files (optional) 
    call :createSampleInputFiles
    
    echo(
    echo --- simple COPY:
    2>NUL del all.csv
    >NUL copy *.csv all.csv /B
        REM (debugging, optional) show output file
    findstr "^" all.csv
    
    echo(
    echo --- loop COPY:
    2>NUL del all.csv
        REM create empty output file: necessary
    >NUL copy NUL all.csv
    for %%G in (*.csv) do (
      if NOT "%%~G"=="all.csv" (
        >NUL copy all.csv + %%G all.csv /B
            REM add an empty line unconditionally
        >>all.csv echo(
      )
    )
    findstr "^" all.csv
    
    echo(
    echo --- loop TYPE: same as --- loop COPY
    2>NUL del all.csv
        REM create empty output file: possible but not necessary
    rem >NUL copy NUL all.csv
    for %%G in (*.csv) do (
      if NOT "%%~G"=="all.csv" (
        >>all.csv type %%G
            REM add an empty line unconditionally
        >>all.csv echo(
      )
    )
    rem findstr "^" all.csv
    
    echo(
    echo --- loop ECHO:
    2>NUL del all.csv
    >all.csv (
      for /F "delims=" %%G in ('dir /b *.csv') do (
        if NOT "%%~G"=="all.csv" (
          for /F "usebackq tokens=*" %%g in ( "%%~G" ) do (
                REM ToDo: (optional) if not 1st file then skip copying CSV header  
            echo(%%g
          )
        )
      )
    )
    findstr "^" all.csv
    
        REM for completeness - add <CR><LF> in advance, then simple COPY:
    echo(
    echo --- add ^<CR^>^<LF^> before simple COPY: same as --- loop COPY 
    2>NUL del all.csv
    for %%G in ( *.csv ) do >>"%%~G" echo(
    >NUL copy *.csv all.csv /B
    rem findstr "^" all.csv
    
        REM change directory back to the path/folder most recently stored by PUSHD
    popd
    
    ENDLOCAL
    goto :eof
    
    :createSampleInputFiles
          REM create sample input files 
      2>NUL del *.csv
      for %%g in ( x y z ) do (
        >i%%g.csv (
              REM write CSV header (optional)
          rem echo(Ca,Cb,Cc
          for %%G in ( 1 2 ) do (
            echo(a%%g%%G,b%%g%%G,c%%g%%G
          )
          if "%%g"=="x" (
                REM last line with trailing <CR><LF>
            echo(a%%gL,b%%gL,c%%gL
          ) else (
                REM last line without trailing <CR><LF>
            <NUL set /P "=a%%gL,b%%gL,c%%gL"
          )
        )
      )
          REM show sample input files
      rem type *.csv
    goto :eof
    

    输出

    d:\bat> D:\bat\SO\40682173.bat
    
    --- simple COPY:
    ax1,bx1,cx1
    ax2,bx2,cx2
    axL,bxL,cxL
    ay1,by1,cy1
    ay2,by2,cy2
    ayL,byL,cyLaz1,bz1,cz1
    az2,bz2,cz2
    azL,bzL,czL
    --- loop COPY:
    ax1,bx1,cx1
    ax2,bx2,cx2
    axL,bxL,cxL
    
    ay1,by1,cy1
    ay2,by2,cy2
    ayL,byL,cyL
    az1,bz1,cz1
    az2,bz2,cz2
    azL,bzL,czL
    
    --- loop TYPE: same as --- loop COPY
    
    --- loop ECHO:
    ax1,bx1,cx1
    ax2,bx2,cx2
    axL,bxL,cxL
    ay1,by1,cy1
    ay2,by2,cy2
    ayL,byL,cyL
    az1,bz1,cz1
    az2,bz2,cz2
    azL,bzL,czL
    
    --- add <CR><LF> before simple COPY: same as --- loop COPY
    
    d:\bat>
    

    【讨论】:

      猜你喜欢
      • 2018-10-20
      • 2016-05-04
      • 2016-05-22
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 2018-08-19
      相关资源
      最近更新 更多