Fügen Sie eine Spalte aus einer CSV-Datei zu einer anderen CSV-Datei hinzu


12

file1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

file2.csv

A,B
A,B
A,B
A,B

gewünschte Ausgabe.csv

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

Ich habe versucht, "verbinden" und "einfügen" ohne Erfolg. Gibt es einen Bash-Befehl, um dies zu tun? Die Spalte "A" ist in beiden .csvDateien gleich.


Sie möchten also Spalte B in Datei 1 kopieren? Oder Spalten C und D nach Datei2?
Tim

So oder so wäre es in Ordnung, solange die Ausgabe mit "desiredOutput.csv"
übereinstimmt

Ich habe eine neue Antwort hinzugefügt, die meiner Meinung nach einfacher ist als alle anderen Antworten (einschließlich meiner ersten Antwort). Möglicherweise möchten Sie dies akzeptieren, damit die Informationen für zukünftige Referenzzwecke leicht gefunden werden können.
don.joey

Antworten:


11

Mit nur awkBefehl:

awk -F, '{getline f1 <"file2" ;print f1,$3,$4}' OFS=, file1

Holen Sie sich eine Zeile aus Datei1 und speichern Sie sie in der lokalen Variablen f1. Drucken Sie dann die Zeile, die in Datei1 gespeichert ist, f1und drucken Sie schließlich das dritte ( $3) und $3vierte ( ) Feld aus, das durch Komma ,getrennt ist Standard]) zu Komma ( ,).


Der Kurzbefehl würde so aussehen:

paste -d, file2 <(cut -d, -f3- file1)
 A B C D  
 A B C D  
 A B C D  
 A B C D  

Fügen Sie die Datei2 ein, schneiden Sie dann die dritte Spalte aus und fügen Sie sie in die nächste ( -f3-) von Datei1 ein.


Mit awkund paste(Option A)

Der folgende Befehl kopiert auch die letzten beiden Spalten ( C,D) aus Datei1 am Ende jeder Zeile in Datei2:

paste -d',' file2  <(awk -F',' '{print $(NF-1)","$NF}' file1)

Obiger Befehl fügen Sie dann der file2 Inhalt ein Komma als Trennzeichen drucken ( -d',') fügen Sie anschließend das zwei letzte Feld ( NFist der Index des letzten Feldes und $NFist der String , den sein Index ist NF. Also $(NF-1)das zweite Feld vor dem letzten Feld) von Datei1 , wenn dieser Index neu definiert oder teilt mit Komma Zuschauer ( -F',').

Mit awkund paste(Option B)

Dieser Befehl ist auch derselbe wie oben ( $3und $4zeigt auf das dritte und vierte Feld jeder Zeile aus Datei1):

paste -d',' file2  <(awk -F',' '{print $3","$4}' file1)

Oder eine andere Lösung mit cutBefehl:

paste -d, <(cut -d, -f1 file1) <(cut -d, -f2 file2) <(cut -d, -f3- file1)

Befehl cut im obigen Befehl schneide zuerst das erste Feld ( -f1das mit Komma-Trennzeichen ( -d.) indiziert wurde ) aus file1 ( cut -d, -f1 file1) aus, dann schneide das zweite Feld von file2 () aus und füge es abschließend aus und füge cut -d, -f2 file2die dritte Spalte ( -f3) in die nächsten ( -) ein von file1 ( cut -d, -f3- file1) wieder.

Dieser Befehl gibt auch das gleiche Ergebnis zurück:

paste -d, <(awk -F',' '{print $1}' file1) <(awk -F',' '{print $2}' file2) <(awk -F',' '{print $3","$4}' file1)

Einfügen des zweiten Feldes aus Datei1 ( awk -F',' '{print $1}' file1), Drucken eines Kommas ( -d,), Einfügen der zweiten Spalte aus Datei2 ( awk -F',' '{print $2}' file2) und erneutes Einfügen der zweiten und letzten Spalte von Datei1 ( awk -F',' '{print $3","$4}' file1).


@kasi du könntest das durch awk selber machen. Siehe stackoverflow.com/a/14984673/3297613
Avinash Raj,

9

Hier ist eine Schönheit (denke ich):

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

In Schritten unterteilt:

Schritt 1. csvkit installieren:

sudo pip install csvkit
sudo apt-get install python-dev python-pip python-setuptools build-essential

Schritt 2. Verwenden Sie den Befehl join mit einem Komma als Trennzeichen

join -t,

Schritt 3. Geben Sie die gewünschten Spalten ein. Beachten Sie, wie Sie die erste Spalte zweimal füttern, da dies diejenige ist, für die der Join tatsächlich ausgeführt wird (Standardverhalten von join).

join -t, <(csvcut --columns 1,3,4 file1.csv) <(csvcut --columns 1,2 file2.csv)

oder in Kurzform:

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

Sie können diese Standardausgabe bei Bedarf in eine Datei (desiredOutput) umleiten.

Vorteile

Dieses Verfahren hat mehrere Vorteile gegenüber den anderen vorgeschlagenen.

In erster Linie: Es führt eine echte Verknüpfung durch. Dies bedeutet, dass es auch für komplexere Daten verwendet werden kann. Es ist zum Beispiel sehr einfach, einen Join in einem anderen Feld durchzuführen. Es wird nicht nur die Position des Feldes betrachtet, sondern die Spalte wird wirklich berücksichtigt. Es funktioniert tatsächlich mit dem Format der Daten (csv) und behandelt sie nicht wie Text.

Zweitens wird das sehr leistungsfähige csv-Toolkit verwendet, mit dem Sie a) Statistiken mit einem Befehl anzeigen ( csvstats), b) überprüfen können, ob die Daten sauber sind ( csvclean), aber auch in json, in sql oder sogar laden können Python! Dieses Toolkit wird in der Datenwissenschaft häufig für die Datenaufbereitung verwendet.


Wenn Sie unter Ubuntu installieren, müssen Sie möglicherweise die Python-Entwicklungs-Header installieren, bevor Sie csvkit installieren können: sudo apt-get install python-dev python-pip python-setuptools build-essential- link
karel

Tolle Antwort, ich arbeite auf einem Unternehmensserver. Die Installation von Dingen dauert also ungefähr eine Woche. Funktioniert aber auf meiner Maschine!
Roboman1723

+1 für das Anzeigen eines anderen Tools für CSV-Daten. Separate Frage, aber kennen Sie einen eigenständigen Reportwriter für CSV-Datendateien?
Joe

@ Joe, kannst du etwas genauer sagen, was du meinst, wenn du über einen 'Reportwriter' sprichst? Ich bin nicht sicher, ob ich verstehe, was du meinst.
don.joey

Ich habe eine separate Frage unter unix.stackexchange.com/questions/170199/…
Joe,

7

Hier ist noch eine schöne. Ich denke, es ist der bisher einfachste aller Vorschläge.

csvtool pastecol 2 2 file1.csv file2.csv

Wenn Sie csvtool in der Vergangenheit noch nicht installiert haben, müssen Sie dies tun sudo apt-get install csvtool.

Aus den Dokumenten:

pastecol <column-spec1> <column-spec2> input.csv update.csv

Ersetzen Sie den Inhalt der Spalten, auf die in der Datei input.csv verwiesen wird, durch den Inhalt der entsprechenden Spalte, die in update.csv angegeben ist.

Beispiel:

  csvtool pastecol 2-3 1- input.csv update.csv.csv > output.csv

Beachten Sie, wie wir in unserem Fall die zweiten Spalten der Dateien ersetzen.

Beispiele

file1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

file2.csv

A,B
A,B
A,B
A,B

Kombinieren der beiden Dateien:

csvtool pastecol 2 2 file1.csv file2.csv
A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

Was Sie im Wesentlichen tun, ist das Einfügen der zweiten Spalte file2.csvals Spalte 2 in file1.csv.

Beachten Sie, dass dies auch für dasselbe Dokument funktioniert. Wenn Sie zwei Spalten austauschen möchten, können Sie dieselbe Datei wie input.csv und update.vsc verwenden.

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A

Ohne Zweifel das eleganteste.
Jacob Vlijm

2

So verschieben Sie eine ausgewählte Anzahl von Spalten von einer Datei in eine andere:

#!/usr/bin/env python3

cols = 1; file_1 = "/path/to/file_1"; file_2 = "/path/to/file_2"

def readfile(file):
      with open(file) as src:
          return [item.strip().split(",") for item in src.readlines()]

file_1 = readfile(file_1); file_2 = readfile(file_2)

for i in range(len(file_1)):
    print((",").join(file_1[i]+file_2[i][-cols:]))

aus zwei Dateien:

file_1

A,B
A,B
A,B
A,B

file_2

K,L,M
K,L,M
K,L,M
K,L,M

Wenn Sie einstellen cols = 1:

A,B,M
A,B,M
A,B,M
A,B,M

Aber wenn Sie einstellen cols = 2:

A,B,L,M
A,B,L,M
A,B,L,M
A,B,L,M

cols = 3:

A,B,K,L,M
A,B,K,L,M
A,B,K,L,M
A,B,K,L,M

Wie benutzt man

Kopieren Sie es in eine leere Datei, den Pfad zu file1, file2und die Anzahl der Spalten zu verschieben, speichern Sie es als move.pyund führen Sie es durch:

python3 /path/to/move.py

Auf diese Weise können Sie auch eine oder mehrere Spalten aus der Mitte der Quellendateispalten hinzufügen.


Hätte dich aber import csvgerne benutzt.
don.joey

@ don.joey Danke für den Vorschlag, werde mich auf jeden Fall darum kümmern.
Jacob Vlijm

0

Eine andere Methode in Python durch CSV-Modul.

script.py

#!/usr/bin/python3
import csv
import sys
file1 = sys.argv[1]
file2 = sys.argv[2]
with open(file2, 'r') as r:
    with open(file1, 'r') as f:
        csv_f = csv.reader(f)
        csv_r = csv.reader(r)
        bar = [linex for linex in csv_r]
        foo = [liney[2:] for liney in csv_f]
        zipped = zip(bar,foo)
        result = [x+y for (x,y) in list(zipped)]
        for i in result:
            print(','.join(i))

Um das obige Skript auszuführen,

python3 script.py file1 file2

Ausgabe:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
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.