Zusammenführen mehrerer CSV-Dateien ohne Zusammenführen des Headers


20

Ich muss mehrere CSV-Dateien zusammenführen (mithilfe des catBefehls), ohne jedoch den Header für jede Datei zu kopieren.

Was ist der beste Weg, um diese Aufgabe zu erfüllen?

Antworten:


32

Sie benötigen mehr als den hiercat beschriebenen Befehl :

Angenommen , Sie haben drei CSV-Dateien: file1.csv, file2.csv, und file3.csvund wollen , dass sie beitreten bigfile.csvund Ihre Header ist immer (nur) die erste Zeile, dann Gebrauch

entweder (Kopfzeile der ersten Datei "file1.csv" beibehalten):

cat file1.csv <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv

oder (Kopfzeile aus allen Dateien entfernen, deren Namen mit "file" beginnen):

awk 'FNR > 1' file*.csv > bigfile.csv

4
Ich fand das nach einer generischen Linux-Antwort suchend, aber in meinem Fall funktionierte das nicht genau. Die Datei file1.csv würde unbemerkt ignoriert. Ich musste diese Datei katzen. cat <(cat file1.csv) <(tail +2 file2.csv) <(tail +2 file3.csv) > bigfile.csv
Lelon

Ich erhalte Tail + 2: Befehl nicht gefunden, als ich Cat <file1.csv <(Tail +2 file2.csv) <(Tail +2 file3.csv)> verwendete. Bigfile.csv-Methode

@ user64636 zwischen tail und +2 sollte ein Leerzeichen stehen
nohillside

Eigentlich musste ich verwenden tail -n+2, tail +2würde nicht funktionieren
Matthieu Napoli

11

Ich bin mit der Top-Antwort einverstanden, schlage aber vor, sie mit dem folgenden Szenario zu erweitern (da ich keine Kommentare abgeben kann):

Wenn die Ausgabedatei (einmal) Header enthalten soll, lautet das richtige Skript:

awk '(NR == 1) || (FNR > 1)' file*.csv > bigfile.csv

FNR repräsentiert die Nummer des verarbeiteten Datensatzes in einer einzelnen Datei. Und NR repräsentiert es global, so dass die erste Zeile akzeptiert wird und der Rest wie zuvor ignoriert wird.


6

Sie können auch einen Gruppenbefehl ( { ; }) anstelle der Prozessersetzung ( <()) verwenden:

{ head -n1 file1.csv; for f in file*.csv; do tail -n+2 "$f"; done; } > new.csv

Es funktioniert auch mit CRLF-Zeilenenden, solange die Dateien mit einer leeren Zeile enden ( \r\n).

Die Nur-Zahlen-Versionen von head und tail wurden durch POSIX 1003.1-2001 überholt und führen in einigen Umgebungen zu Warnungen.


2

Wird benötigt, um zwei große CSVs mit identischen Spalten zu einer größeren CSV für Chunking-Skripts zu verknüpfen (Daten haben keine eindeutigen IDs).

Zuerst wurde der Kopfball aus dem zweiten csv entfernt

awk 'FNR > 1' file2.csv > file2_noheading.csv

Als nächstes verkettet über die folgenden

cat file1.csv file2_noheading.csv > newfile.csv

1

Die Verwendung der obigen Befehlssequenz ergab eine Datei, die wie folgt aussah:

header,of,csv1
contents,of,csv1
==> csv2.csv

contents,of,csv2

Um eine korrekte CSV-Datei mit einer Kopfzeile und allen relevanten Werten zu erstellen, habe ich die folgende sedBeschwörung angewendet ...sed -ie "/^$/d;/^==>/d" bigfile.csv


0

Einfachere Lösung, wenn Sie eine Menge Dateien haben:

awk 'FNR > 1' *.csv > merged.csv

Gehen Sie einfach zurück, um die große Datei zu bearbeiten, und fügen Sie den Header wieder hinzu.


Inwiefern unterscheidet sich Ihre Antwort von der von iolsmit 2013 vorgestellten awk 'FNR > 1' file*.csv > bigfile.csv? Es ist nicht!
user3439894

Re: wie ist es anders? Es ist eine knappe Antwort und die, die ich zumindest kopiert und eingefügt habe:) Bekomme meine Zustimmung
Rick Davies

Dies ist eine gute Antwort, da Sie nicht alle Dateien benötigen, um zu beginnenfile
big_smile
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.