2013-12-16 5 views
20

У меня очень большой CSV-файл (> 500 Мб), и я хочу разбить его на меньшие .csv-файлы в командной строке. (В основном пытается найти функцию разделения «linux» в Windows ».Пакетный файл для разделения .csv-файла

Это должен быть пакетный скрипт, так как моя машина имеет только установленные окна и запрашивает программное обеспечение. Я наткнулся на несколько примеров кода (http://forums.techguy.org/software-development/1023949-split-100000-line-csv-into.html), однако, он не работает, когда я выполняю пакет. Все, что я получаю, это один выходной файл, который составляет всего 125 КБ, когда я попросил его разобрать каждые 20 000 строк.

Неужели кто-нибудь сталкивался с подобной проблемой и как ? вы решить вопрос

+0

Если вы используете Windows, то это не DOS. Вы говорите о командной строке Windows (cmd.exe). – dbenham

+0

Используйте расщепление с [GnuWin CoreUtils] (http://gnuwin32.sourceforge.net/packages/coreutils.htm)? – seumas

+0

Мысль об этом, но снова его боль, чтобы получить программное обеспечение на моем месте работы. Эта проблема была решена благодаря всем, что способствовало. – SeekingAlpha

ответ

28

Попробуйте это:

@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 с лимитом в 20 000 строк. Все, что вам нужно сделать, это изменить соответственно переменную !file! и !limit!. Надеюсь, поможет.

+0

На моем ПК (ядро i7) это занимает около 30 секунд на мегабайт. Дайте ему 4 часа, и он разделит ваши 500 MB csv. – indiv

+0

Спасибо Dale, К сожалению, этот код дает тот же результат, что и ссылка, которую я дал. Вывел файл 126kb с тем же именем, и содержимое было почти идентично тому, что я делал ранее. – SeekingAlpha

+0

Эй, Марко, могу я знать, каков ваш ожидаемый результат? – Dale

1

Это даст вам линии 1 to 20000 в newfile1.csv
и линий 20001 to the end в файле newfile2.csv

Он преодолевает ограничение на количество символов в строке 8K тоже.

Это использует вспомогательный командный файл findrepl.bat из - https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat

Место findrepl.bat в той же папке, что и пакетный файл или на пути.

Это более надежный, чем простой командный файл, и быстрее.

findrepl /o:1:20000 <file.csv >newfile1.csv 
findrepl /o:20001 <file.csv >newfile2.csv 
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 
6

Используйте команду cgwin SPLIT. Образцы -Сплит файл каждые 500 строк отсчитывает: раскол -l 500 [имяфайла.рсш]

Для более: расколоть --help

+0

Файл размером 6.09 GB (> 32M строк) разделен на 500K строк файлов за несколько секунд !!! – francadaval

27

Бесплатная окна приложение, которое делает этот

http://www.addictivetips.com/windows-tips/csv-splitter-for-windows/

+0

Спасибо, помощник - простой режим! – ThisClark

+0

Хорошая программа. Быстро и легко. –

+0

Феноменальный инструмент, сделал именно то, что мне нужно, супер быстрый и простой в использовании. – ammills01

1

Если вы разбиваете очень большие файлы, решение, которое я нашел, является адаптацией от this, с PowerShell «встроенным» в пакетном файле. Это работает быстро, в отличие от многих других вещей, которые я пробовал (я не знал бы о других вариантах, размещенных здесь).

Способ использования mysplit.bat ниже

mysplit.bat <mysize> 'myfile'

Примечание: Сценарий предназначен для использования в первый аргумент как размер разделения. В настоящее время он жестко закодирован со скоростью 100 Мб. Нетрудно это исправить.

Примечание 2: Имя файла должно быть заключено в одинарные кавычки. Другие альтернативы цитирования, по-видимому, не работают.

Примечание 3: Он разбивает файл на заданное количество байтов, а не на заданное количество строк. Для меня это было достаточно хорошо. Некоторые строки кода могут быть добавлены, чтобы завершить чтение каждого фрагмента, вплоть до следующего CR/LF. Это будет разделено на полные строки (не с их постоянным числом), без потерь во время обработки.

Script 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% 
+0

Разделение 'csv' на несколько байтов может быть не лучшим из всех идей. Строки не должны разделяться. – Stephan

+0

@Stephan - Я думаю, что ваше утверждение может быть или не быть правдой.Все зависит от того, что нужно. Мне на самом деле нужно было расщепить огромный csv, и делать это по заданным номерам строк или по заданным номерам байт работало одинаково хорошо. На самом деле это потребовало, чтобы я собрал этот сценарий. –

+0

, конечно, это зависит от ваших потребностей. Просто хотел отметить. Окончание 'csv' или начало в середине значения где-то посередине строки кажется мне кошмаром. Но f это не имеет значения, это, кажется, хороший ответ (и единственный, который разделяет на размер вместо linenumbers). – Stephan

Смежные вопросы