Wie teile ich CSV-Dateien nach der angegebenen Anzahl von Zeilen?

81

Ich habe eine CSV-Datei (ca. 10.000 Zeilen; jede Zeile hat 300 Spalten) auf dem LINUX-Server gespeichert. Ich möchte diese CSV-Datei in 500 CSV-Dateien mit jeweils 20 Datensätzen aufteilen. (Jeder hat den gleichen CSV-Header wie in der ursprünglichen CSV)

Gibt es einen Linux-Befehl, der diese Konvertierung unterstützt?

Pawan Mude
quelle
1
Dies funktioniert zwar, der Header der ersten Datei wird jedoch dupliziert, wodurch die Header der ersten CSV-Datei 2 erhalten werden.
Rickman

Antworten:

78

Hat es zu einer Funktion gemacht. Sie können jetzt anrufensplitCsv <Filename> [chunkSize]

splitCsv() {
    HEADER=$(head -1 $1)
    if [ -n "$2" ]; then
        CHUNK=$2
    else 
        CHUNK=1000
    fi
    tail -n +2 $1 | split -l $CHUNK - $1_split_
    for i in $1_split_*; do
        sed -i -e "1i$HEADER" "$i"
    done
}

Gefunden unter: http://edmondscommerce.github.io/linux/linux-split-file-eg-csv-and-keep-header-row.html

Martin Dinov
quelle
1
Können Sie erklären, wie es funktioniert? Ich habe den ursprünglichen Beitrag überprüft, aber es gibt auch keine Erklärung und nicht einmal die Möglichkeit, Kommentare zu veröffentlichen.
Shashi009
6
Was ist, wenn eine Zelle in CSV eine neue Zeile enthält?
Ondřej Hlaváček
Was ist das für ein Zeilenumbruch? Bei UTF-8 funktioniert es immer noch, ich bin mir nicht sicher, ob dies hilft.
Owyongsk
3
@ shashi009: Angenommen, die Originaldatei heißt file.txt. 1: die erste Zeile, dann Rohr des Rest der Datei in überspringen split, die Splits in neue Dateien mit jeweils 20 Zeilen lang, mit dem Präfix split_2: eine Iteration durch die neuen split_ * Dateien, jeden Namen auf die Variable speichert file, einen nach dem anderen 3: für jede ... 4: Schreiben Sie die erste Zeile (Spaltenüberschriften) aus unserer Originaldatei in eine tmp_file 5: Fügen Sie die 20-Zeilen-Split-Datei an tmp_file 6 an: Überschreiben Sie die alte split_ * -Datei mit der neuen tmp_file, damit die Spaltenüberschriften erhalten bleiben
David
1
Das Vorstellen des Headers über echo -e "$HEADER\n$(cat $i)" > $iist unnötig unverformbar. Ich habe es durch ersetzt sed -i -e "1i$HEADER" "$i".
Philipp Moers
139

Verwenden Sie den Linux-Split-Befehl:

split -l 20 file.txt new    

Teilen Sie die Datei "file.txt" in Dateien auf, die mit dem Namen "new" beginnen und jeweils 20 Textzeilen enthalten.

Geben Sie man splitan der Unix-Eingabeaufforderung weitere Informationen ein. Sie müssen jedoch zuerst den Header aus file.txt entfernen ( tailz. B. mit dem Befehl) und ihn dann wieder zu jeder der geteilten Dateien hinzufügen.

James King
quelle
Wie kann ich die erste Zeile (file.txt) von file.txt überspringen?
Gabelgabel
Verwenden wc -lSie diese Option, um die Anzahl der Zeilen abzurufen. Nehmen Sie dann diesen Wert, subtrahieren Sie 1 (nehmen Sie an, dass dies wc -l50 ergibt ) und führen Sie dann tail -n 49(in diesem Beispiel) aus, um alles außer der Kopfzeile abzurufen. Beachten Sie, dass wc -l<newline> -Zeichen gezählt werden. Wenn die letzte Zeile nicht mit einem Newline-Zeichen endet, ist die Anzahl der Zeilen um 1 verringert.
Lucas Roberts
3
@lucas, tail -n +2 druckt alle Zeilen außer der ersten.
James King
@ JamesKing, +1 & Danke! Ich sollte die Dokumente genauer lesen :)
Lucas Roberts
5
--additional-suffix=.csv
Um
21

Das sollte funktionieren !!!

file_name= Name der Datei, die Sie teilen möchten.
10000= Anzahl der Zeilen, die jede geteilte Datei enthalten würde
file_part_= Präfix des geteilten Dateinamens (file_part_0, file_part_1, file_part_2..etc geht weiter)

split -d -l 10000 file_name.csv file_part_

Koralle
quelle
das funktioniert absolut gut! Gibt es eine Möglichkeit, die Anzahl der von mir erstellten 10000 Zeilendateien zu begrenzen? Angenommen, ich möchte nur die ersten 200.000 Zeilen in 10.000-Zeilen-CSV-Dateien unterteilen und den Rest ignorieren.
Pronomita Dey
1
@Pronomitahead -200000 file.csv | split -l 10000 - new_
Boloyao
2
Ich hatte eine 13-Gbit-CSV-Datei mit einer beschädigten Zeile bei ungefähr 69 000 000. Sie blockierte den Import in BigQuery. Dadurch konnte ich es rekursiv teilen, bis ich die Linie isolieren und reparieren konnte. Keine andere Lösung war so effizient bei der Verarbeitung großer Dateien, ohne den Server herunterzufahren oder zu blockieren. Es dauerte ungefähr 2 Minuten, um die Datei in 5 000 000 Zeilenabschnitte aufzuteilen. Vielen Dank!
LP Papillon
13

Dies sollte es für Sie tun - alle Ihre Dateien werden am Ende Part1-Part500 genannt.

#!/bin/bash
FILENAME=10000.csv
HDR=$(head -1 $FILENAME)   # Pick up CSV header line to apply to each file
split -l 20 $FILENAME xyz  # Split the file into chunks of 20 lines each
n=1
for f in xyz*              # Go through all newly created chunks
do
   echo $HDR > Part${n}    # Write out header to new file called "Part(n)"
   cat $f >> Part${n}      # Add in the 20 lines from the "split" command
   rm $f                   # Remove temporary file
   ((n++))                 # Increment name of output part
done
Mark Setchell
quelle
Dadurch wurden die Dateien erstellt, aber Tabulatoren (ich meine \ t) wurden durch Leerzeichen ersetzt, und meine CSV-Dateien verwendeten \ t als Trennzeichen
AmineG
Dies kann leicht verbessert werden, indem die Zahlen aufgefüllt werden, sodass die Dateien nacheinander automatisch angezeigt werden. Durch Ersetzen des $ {n} durch $ (printf "% 05d \ n" $ n)
Phineas Dashevsky
4
Die Kopfzeile wird in der ersten Datei dupliziert.
Juha Palomäki