web-dev-qa-db-fra.com

Fichier de commandes pour diviser le fichier .csv

J'ai un très gros fichier .csv (> 500 Mo) et je souhaite le scinder en fichiers .csv plus petits dans l'invite de commande. (Essentiellement, essayer de trouver une fonction "split" sous Linux ".

Ce doit être un script batch car ma machine n’a que Windows installé et il est difficile de demander des logiciels. Je suis tombé sur plusieurs exemples de codes ( http://forums.techguy.org/software-development/1023949-split-100000-line-csv-into.html ), mais ce n'est pas le cas. travaille quand j'exécute le lot. Tout ce que je reçois est un fichier de sortie qui ne pèse que 125 ko lorsque je l’ai demandé d’analyser toutes les 20 000 lignes.

Quelqu'un at-il déjà rencontré un problème similaire et comment avez-vous résolu le problème?

29
SeekingAlpha

Essayez ceci:

@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
)

Comme indiqué dans le code ci-dessus, le fichier csv d'origine sera divisé en plusieurs fichiers csv avec une limite de 20 000 lignes. Tout ce que vous avez à faire est de changer le !file! et !limit! variable en conséquence. J'espère que ça aide.

37
Dale

Une application Windows gratuite qui fait ça

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

38
Gonki

Utilisez la commande cgwin SPLIT. Des échantillons

Pour fractionner un fichier toutes les 500 lignes:

split -l 500 [filename.ext]

par défaut, il ajoute xa, xb, xc ... au nom de fichier après extension

Pour générer des fichiers avec des nombres et se terminant par l’extension correcte, utilisez la commande suivante

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

la position de -d ou -l n'a pas d'importance,

  • "- d" est identique à −− numérique - suffixes
  • "- l" est identique à - lignes

Pour plus: split --help

13
hhh

Si vous divisez de très gros fichiers, la solution que j'ai trouvée est une adaptation de this , avec PowerShell "intégré" dans un fichier de traitement par lots. Cela fonctionne rapidement , par opposition à beaucoup d'autres choses que j'ai essayées (je ne saurais rien des autres options publiées ici).

La façon d'utiliser mysplit.bat ci-dessous est

mysplit.bat <mysize> 'myfile'

Remarque: le script était destiné à utiliser le premier argument comme taille de division. Il est actuellement codé en dur à 100 Mo. Il ne devrait pas être difficile de résoudre ce problème.

Note 2: Le nom de fichier doit être entre guillemets simples. D'autres alternatives pour citer apparemment ne fonctionnent pas.

Remarque 3: Il divise le fichier avec un nombre d'octets donné et non avec un nombre de lignes donné. Pour moi c'était assez bon. Certaines lignes de code pourraient probablement être ajoutées pour compléter chaque lecture de morceau, jusqu'au CR/LF suivant. Cela se scinde en lignes complètes (pas avec un nombre constant), sans sacrifier le temps de traitement.

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%
3
sancho.s

J'ai trouvé cette question en cherchant une solution similaire. J'ai modifié la réponse donnée par @Dale pour répondre à mes besoins. Je voulais quelque chose qui était un peu plus flexible et avait un piège d'erreur. J'ai pensé que je pourrais le mettre ici pour ceux qui recherchent la même chose.

@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
0
SuperMykEl

Cela vous donnera des lignes 1 to 20000 dans newfile1.csv
et lignes 20001 to the end dans le fichier newfile2.csv

Il dépasse également la limite de 8 000 caractères par ligne.

Ceci utilise un fichier de commandes auxiliaire appelé findrepl.bat de - https://www.dropbox.com/s/rfdldmcb6vwi9xc/findrepl.bat

Endroit findrepl.bat dans le même dossier que le fichier de commandes ou sur le chemin.

Il est plus robuste qu'un fichier de commandes ordinaire et plus rapide.

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