用于拆分.csv文件的批处理文件

时间:2013-12-16 03:14:46

标签: windows batch-file csv command-prompt

我有一个非常大的.csv文件(> 500mb),我希望在命令提示符中将其分解为更小的.csv文件。 (基本上试图在Windows中找到Linux“拆分”功能“。

这必须是一个批处理脚本,因为我的机器只安装了Windows并且请求软件很痛苦。我遇到了许多示例代码(http://forums.techguy.org/software-development/1023949-split-100000-line-csv-into.html),但是,当我执行批处理时,它不起作用。我得到的只是一个输出文件,当我要求它解析每20 000行时只有125kb。

有没有人遇到类似的问题,你是如何解决这个问题的?

6 个答案:

答案 0 :(得分:36)

试试这个:

@echo off
setLocal EnableDelayedExpansion

set limit=20000
set file=export.csv
set lineCounter=1
set filenameCounter=1

set name=
set extension=
for %%a in (%file%) do (
    set "name=%%~na"
    set "extension=%%~xa"
)

for /f "tokens=*" %%a in (%file%) do (
    set splitFile=!name!-part!filenameCounter!!extension!
    if !lineCounter! gtr !limit! (
        set /a filenameCounter=!filenameCounter! + 1
        set lineCounter=1
        echo Created !splitFile!.
    )
    echo %%a>> !splitFile!

    set /a lineCounter=!lineCounter! + 1
)

如上面的代码所示,它会将原始csv文件拆分为多个csv文件,限制为20000行。您所要做的就是相应地更改!file!!limit!变量。希望能帮助到你。

答案 1 :(得分:35)

答案 2 :(得分:10)

使用cgwin命令SPLIT。 样品

每隔500行分割一个文件:

split -l 500 [filename.ext]

默认情况下,它会在扩展名

之后将xa,xb,xc ...添加到文件名

要生成带有数字并以正确扩展名结尾的文件,请使用以下

split -l 1000 sourcefilename.ext destinationfilename -d --additional-suffix=.ext

-d或-l的位置无关紧要,

  • " -d" - 数字后缀
  • 相同
  • " -l" - 行
  • 相同

更多信息:split --help

答案 3 :(得分:3)

如果拆分非常大的文件,我找到的解决方案是来自this的改编,使用PowerShell"嵌入"在批处理文件中。 这很快,而不是我尝试的其他许多东西(我不会知道这里发布的其他选项)。

下面使用mysplit.bat的方法是

  

mysplit.bat <mysize> 'myfile'

注意:该脚本旨在使用第一个参数作为拆分大小。它目前硬编码为100Mb。解决这个问题应该不难。

注2:filname应用单引号括起来。引用的其他替代方案显然不起作用。

注3:它以给定的字节数分割文件,而不是给定的行数。对我来说,这已经足够了。 可能会添加一些代码行来完成每个块读取,直到下一个CR / LF。这将以实线(不是恒定数量)分割,不会牺牲处理时间。

脚本mysplit.bat

@REM Using https://stackoverflow.com/questions/19335004/how-to-run-a-powershell-script-from-a-batch-file
@REM and https://stackoverflow.com/questions/1001776/how-can-i-split-a-text-file-using-powershell
@PowerShell  ^
    $upperBound = 100MB;  ^
    $rootName = %2;  ^
    $from = $rootName;  ^
    $fromFile = [io.file]::OpenRead($from);  ^
    $buff = new-object byte[] $upperBound;  ^
    $count = $idx = 0;  ^
    try {  ^
        do {  ^
            'Reading ' + $upperBound;  ^
            $count = $fromFile.Read($buff, 0, $buff.Length);  ^
            if ($count -gt 0) {  ^
                $to = '{0}.{1}' -f ($rootName, $idx);  ^
                $toFile = [io.file]::OpenWrite($to);  ^
                try {  ^
                    'Writing ' + $count + ' to ' + $to;  ^
                    $tofile.Write($buff, 0, $count);  ^
                } finally {  ^
                    $tofile.Close();  ^
                }  ^
            }  ^
            $idx ++;  ^
        } while ($count -gt 0);  ^
    }  ^
    finally {  ^
        $fromFile.Close();  ^
    }  ^
%End PowerShell%

答案 4 :(得分:0)

这会在1 to 20000中为您提供newfile1.csv行 文件20001 to the end

中的行newfile2.csv

它也克服了每行8K字符限制。

这使用了来自 - https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat

的名为findrepl.bat的帮助程序批处理文件

findrepl.bat放在与批处理文件相同的文件夹中或路径上。

它比普通批处理文件更强大,也更快。

findrepl /o:1:20000 <file.csv >newfile1.csv
findrepl /o:20001   <file.csv >newfile2.csv

答案 5 :(得分:0)

我在寻找类似的解决方案时发现了这个问题。我修改了@Dale给出的答案以满足我的目的。我想要一些更灵活的东西并且有一些错误捕获。我想我可能会把它放在任何寻找相同事物的人身上。

@echo off
setLocal EnableDelayedExpansion
GOTO checkvars

:checkvars
    IF "%1"=="" GOTO syntaxerror
    IF NOT "%1"=="-f"  GOTO syntaxerror
    IF %2=="" GOTO syntaxerror
    IF NOT EXIST %2 GOTO nofile
    IF "%3"=="" GOTO syntaxerror
    IF NOT "%3"=="-n" GOTO syntaxerror
    IF "%4"==""  GOTO syntaxerror
    set param=%4
    echo %param%| findstr /xr "[1-9][0-9]* 0" >nul && (
        goto proceed
    ) || (
        echo %param% is NOT a valid number
        goto syntaxerror
    )

:proceed
    set limit=%4
    set file=%2
    set lineCounter=1+%limit%
    set filenameCounter=0

    set name=
    set extension=

    for %%a in (%file%) do (
        set "name=%%~na"
        set "extension=%%~xa"
    )

    for /f "usebackq tokens=*" %%a in (%file%) do (
        if !lineCounter! gtr !limit! (
            set splitFile=!name!_part!filenameCounter!!extension!
            set /a filenameCounter=!filenameCounter! + 1
            set lineCounter=1
            echo Created !splitFile!.
        )
        cls
        echo Adding Line !splitFile! - !lineCounter!
        echo %%a>> !splitFile!
        set /a lineCounter=!lineCounter! + 1
    )
    echo Done!
    goto end
:syntaxerror
    Echo Syntax: %0 -f Filename -n "Number Of Rows Per File"
    goto end
:nofile
    echo %2 does not exist
    goto end
:end