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?

Dranian
quelle

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
Ich sage
quelle
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.

Marek Grác
quelle
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.

Lri
quelle
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
mcconnelljk
quelle
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

hd1
quelle
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.

brian
quelle
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