staging.inyokaproject.org

Wie kann man 2 CSV Dateien zusammenfügen?

Status: Ungelöst | Ubuntu-Version: Server 22.10 (Kinetic Kudu)
Antworten |

rurotil

Anmeldungsdatum:
7. April 2009

Beiträge: Zähle...

Hallo,

ich möchte gerne 2 CSV Dateien zusammenfügen. Aber nicht wie üblich, unten dran hängen, sondern die Spalten sollten hinten dran gehängt werden.

CSV Datei 1

Spalte1; Spalte2; Spalte3;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5

CSV Datei 2

Spalte4; Spalte5; Spalte6;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5

Ergebnis soll so aussehen:

Spalte1; Spalte2; Spalte3; Spalte4; Spalte5; Spalte6;
   1   ;    2     ;   1  ;    1   ;    2     ;   1
   1   ;    1     ;   3  ;    1   ;    1     ;   3
   2   ;    4     ;   5  ;    2   ;    4     ;   5

Habe das schon versucht:

csvjoin -d ";" test1.csv test2.csv > ergebis.csv
 
paste -d";" test1.csv test2.csv > ergebis.csv

cat test1.csv test2.csv >  ergebis.csv

Keines scheint so recht zu funktionieren. csvjoin kommt schon am nächsten, aber danach ist das Komma als Trennzeichen und nicht mehr Semikolon

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

rurotil schrieb:

csvjoin kommt schon am nächsten, aber danach ist das Komma als Trennzeichen und nicht mehr Semikolon

Das ist auch richtig, da CSV „comma separated values“ bedeutet. Das Semikolon ist also ein Fehler, bzw. wäre es dann ein SSV. Oftmals werden auch andere Trennzeichen wie Tabs oder das Semikolon unterstützt, ist aber undefiniert.

Du kannst aber auch einfach paste nehmen:

paste -d';' datei1.csv datei2.csv 

rurotil

(Themenstarter)

Anmeldungsdatum:
7. April 2009

Beiträge: 96

paste hatte ich doch als Beispiel drinnen, aber das funktioniert nicht.

Irgendwie macht er mir die Spalten aus der 2. Datei in die 2 Zeile.

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

rurotil schrieb:

paste hatte ich doch als Beispiel drinnen, aber das funktioniert nicht.

Ja, ist ja auch ein richtiges Beispiel. Nur wissen wir nicht was „funktioniert nicht“ genau bedeutet. Mit deinen Beispieldaten sieht das so aus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
me@desktop[/tmp/bla] cat datei*
Spalte1; Spalte2; Spalte3;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5
Spalte4; Spalte5; Spalte6;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5
me@desktop[/tmp/bla] paste -d';' datei1.csv datei2.csv 
Spalte1; Spalte2; Spalte3;;Spalte4; Spalte5; Spalte6;
   1   ;    2     ;   1;   1   ;    2     ;   1
   1   ;    1     ;   3;   1   ;    1     ;   3
   2   ;    4     ;   5;   2   ;    4     ;   5
me@desktop[/tmp/bla] 

Irgendwie macht er mir die Spalten aus der 2. Datei in die 2 Zeile.

Ich vermute mal Unsauberheiten wie das zusätzliche Semikolon in den Beispieldaten. Da würde es reichen nach Spalte{3,6} das Semikolon zu entfernen. Paste ist halt „dumm“ und klebt nur aneinander.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

ChickenLipsRfun2eat schrieb:

Das ist auch richtig, da CSV „comma separated values“ bedeutet. Das Semikolon ist also ein Fehler, bzw. wäre es dann ein SSV.

Das stimmt nicht ganz. CSV wird auch als unspezifischer Oberbegriff für all die ähnlichen Formate benutzt, egal ob Komma, Tab oder Semicolon. Außerdem wird es aber auch als spezifischer Begriff benutzt, so dass es je nach Kontext das eine oder das andere heißen kann, ähnlich wie Tesafilm.

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

user_unknown schrieb:

Das stimmt nicht ganz. CSV wird auch als unspezifischer Oberbegriff für all die ähnlichen Formate benutzt…

Benutzt schon. Definiert ist es aber nicht. Es sagen ja auch viele „Linux“, obwohl das Betriebssystem GNU ist und der Kernel Linux. Das macht es aber nicht richtig und mWn gibt es auch keine Definition bezüglich anderer Trennzeichen, oder weißt du da mehr?
csvjoin hält sich halt an die Spezifikation, weswegen es Kommata als Trennzeichen nutzt, um technisch korrekte CSV auszugeben.

rurotil

(Themenstarter)

Anmeldungsdatum:
7. April 2009

Beiträge: 96

Ich habe 2 CSV Dateien jeweils ca. 7MB groß mit ca. 10.000 Zeilen. Damit funktionert es jedenfalls nicht.

Bei den CSV Dateien ist am ende nicht immer ein ; liegt vielleicht daran?

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

rurotil schrieb:

Bei den CSV Dateien ist am ende nicht immer ein ; liegt vielleicht daran?

Möglich. Das Ergebnis wäre dann ja wie in den Beispieldaten und ;; wäre eine namenlose Spalte. Dadurch würde sich dann alles verschieben, da in den Zeilen Werte für diese Spalte enthalten sind.

Du kannst es ja testen, indem du die Zeilenenden einheitlich machst. Schwer das ohne konkrete Daten abzuschätzen. Ein Format wie XML oder JSON wäre natürlich stabiler, falls du die Daten auch in dem Format haben kannst. Die Anzahl Zeilen ist in dem Bereich irrelevant.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

Vielleicht ist ein Problem, dass Du nicht sagst, wie die Dateien verkoppelt werden sollen. Dass die Beispieldateien wechselseitig identisch sind macht es schwierig, das zu erraten. Soll es nach der Zeilennummer gehen, oder ist Zeile 1 als Schlüssel zu verwenden? Dann müsste in Datei 2 die erste Spalte aber wohl auch "Spalte1" heißen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
🐧> cat test?.csv 
Spalte1; Spalte2; Spalte3;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5
Spalte1; Spalte5; Spalte6;
   1   ;    2     ;   1
   1   ;    1     ;   3
   2   ;    4     ;   5
🐧> join --nocheck-order -t ";" test1.csv test2.csv 
Spalte1; Spalte2; Spalte3;; Spalte5; Spalte6;
   1   ;    2     ;   1;    2     ;   1
   1   ;    2     ;   1;    1     ;   3
   1   ;    1     ;   3;    2     ;   1
   1   ;    1     ;   3;    1     ;   3
   2   ;    4     ;   5;    4     ;   5

Wenn es nach Zeilennummern gejoint werden soll hilft nl (number lines).

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

ChickenLipsRfun2eat schrieb:

user_unknown schrieb:

Das stimmt nicht ganz. CSV wird auch als unspezifischer Oberbegriff für all die ähnlichen Formate benutzt…

Benutzt schon. Definiert ist es aber nicht. Es sagen ja auch viele „Linux“, obwohl das Betriebssystem GNU ist und der Kernel Linux. Das macht es aber nicht richtig und mWn gibt es auch keine Definition bezüglich anderer Trennzeichen, oder weißt du da mehr?
csvjoin hält sich halt an die Spezifikation, weswegen es Kommata als Trennzeichen nutzt, um technisch korrekte CSV auszugeben.

Csvjoin erlaubt vernünftigerweise ein anderes Zeichen als Trenner zu verwenden, so wie auch join.

Das Semikolon und der Tab kommen in Feldern im Schnitt viel seltener vor, weswegen sie als Trenner besser geeignet sind (Dezimaltrenner in kontinentaler Dezimalzahldarstellung, z.B.).

Die Definition ist natürlich trivial - statt "," trennt man mit Tab bzw. ";".

rurotil

(Themenstarter)

Anmeldungsdatum:
7. April 2009

Beiträge: 96

Von meiner Datei jeweils die erste Zeile

CSV Datei 1:

Id;ReferenceNo;EAN;Manufacturer;Price_Regular;Price_Discounted;PriceDiscountPercent;Price_DiscountAmount;Price_exclVAT;Price_inclVAT;Price_VATRate;Price_VATCountry;Price_Currency;Stock;StockNextDelivery;StockNextDeliveryAccessVolume;WarrantyCode;EOL;Promotion;NonReturnable;RemainingStock;ImagePrimary;ImageAdditional;ProductLink;GrossWeight;NetWeight;RelatedProducts;AccessoryProducts;Description_3422_German;CategoryName_3422_German;CategoryPath_3422_German;WarrantyDescription_3422_German;Description_3421_English;CategoryName_3421_English;CategoryPath_3421_English;WarrantyDescription_3421_English;Description_1036_French;CategoryName_1036_French;CategoryPath_1036_French;WarrantyDescription_1036_French;Description_1043_Dutch;CategoryName_1043_Dutch;CategoryPath_1043_Dutch;WarrantyDescription_1043_Dutch;ProductDisplayType;LicenseTypeCode;LicenseTypeDescription;

CSV Datei 2:

Id;PrintText_3422_German;PrintText_3421_English1;PrintText_1036_French1;PrintText_1043_Dutch1;LongDescription_3422_German;LongDescription_3421_English;LongDescription_1036_French;LongDescription_1043_Dutch;

oder werden doch mehr Zeilen Benötigt?

Woher weiß die CSV Datei eigentlich das eine neue Zeile kommt? Da ist kein / oder sonstiges Zeichen?

rurotil

(Themenstarter)

Anmeldungsdatum:
7. April 2009

Beiträge: 96

Spalte 1 von meiner CSV Datei1:

Id;ReferenceNo;EAN;Manufacturer;Price_Regular;Price_Discounted;Price_DiscountPercent;Price_DiscountAmount;Price_exclVAT;Price_inclVAT;Price_VATRate;Price_VATCountry;Price_B2X_Currency;Stock;StockNextDelivery;StockNextDeliveryAccessVolume;WarrantyCode;EOL;Promotion;NonReturnable;RemainingStock;ImagePrimary;ImageAdditional;ProductLink;GrossWeight;NetWeight;RelatedProducts;AccessoryProducts;Description_2735_German;CategoryName_2735_German;CategoryPath_2735_German;WarrantyDescription_2735_German;Description_2733_English;CategoryName_2733_English;CategoryPath_2733_English;WarrantyDescription_2733_English;Description_2734_French;CategoryName_2734_French;CategoryPath_2734_French;WarrantyDescription_2734_French;Description_1043_Dutch;CategoryName_1043_Dutch;CategoryPath_1043_Dutch;WarrantyDescription_1043_Dutch;ProductDisplayType;LicenseTypeCode;LicenseTypeDescription;

Spalte 1 von meiner CSV Datei2:

Id;PrintText_2735_German;PrintText_2733_English1;PrintText_2734_French1;PrintText_1043_Dutch1;LongDescription_2735_German;LongDescription_2733_English;LongDescription_2734_French;LongDescription_1043_Dutch;

Das war das Ergbnis aus:

join --nocheck-order -t ";" test1.csv test2.csv 

Das Id fehlt hat er zuammengefügt oder? Und aus der ersten CSV fehlen ein paar Spalten, Warum?

Id;ReferenceNo;EAN;Manufacturer;Price_Regular;Price_Discounted;Price_DiscountPercent;Price_DiscountAmount;Price_exclVAT;Price_inclVAT;Price_VATRate;Price_VATCountry;Price_B2X_Currency;Stock;StockNextDelivery;StockNextDeliveryAccessVolume;WarrantyCode;EOL;Promotion;NonReturnable;RemainingStock;ImagePrimary;ImageAdditional;ProductLink;GrossWeight;NetWeight;RelatedProducts;AccessoryProducts;Description_2735_German;CategoryName_2735_German;CategoryPath_2735_German;WarrantyDescription_2735_German;Description_2733_English;CategoryName_2733_English;CategoryPath_2733_English;WarrantyDescription_2733_English;Description_2734_French;CategoryName_2734_French;CategoryPath_2734_French;WarrantyDescription_2734_French;Description_1043_Dutch;CategoryName_1043_Dutch;CategoryPath_1043_Dutch;W;PrintText_2735_German;PrintText_2733_English1;PrintText_2734_French1;PrintText_1043_Dutch1;LongDescription_2735_German;LongDescription_2733_English;LongDescription_2734_French;LongDescription_1043_Dutch;

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

join verschluckt das 'Id'-Feld in der zweiten Datei.

Vergleiche:

join --nocheck-order -t ";" header{1,2}.csv
# mit bspw.
sed 's@;@\n@g' header{1,2}.csv

Du kannst diff -y nehmen, damit es in Spalten angezeigt wird.

rurotil

(Themenstarter)

Anmeldungsdatum:
7. April 2009

Beiträge: 96

Das etwas fehlt, ist mir auch augefallen. Aber warum? oder wie kann ich das verhindern?

ChickenLipsRfun2eat Team-Icon

Supporter
Avatar von ChickenLipsRfun2eat

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12070

Warum kann ich dir auch nicht sagen. join ist auf jeden Fall komplexer als paste, daher vermute ich das entweder deine Daten nicht korrekt sortiert sind oder das Feld Id als Duplikat erkannt und gejoint wird.

Verhindern kommt sehr auf die vorliegenden Daten an. Wenn die sauber vorlägen, wäre paste mein Mittel der Wahl, ansonsten bleibt csvjoin, welches ja funktioniert, dir nur wegen des Trennzeichens unsympathisch ist. Warum eigentlich?

Antworten |