Dodaj kolumnę z jednego pliku .csv do innego pliku .csv

12

plik1.csv

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

plik2.csv

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

pożądany Output.csv

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

Próbowałem użyć „dołącz” i „wklej” bezskutecznie. Czy istnieje do tego polecenie bash? Kolumna „A” jest taka sama w obu .csvplikach.

Roboman1723
źródło
Pytasz więc o skopiowanie kolumny B do pliku 1? Lub kolumny C i D do pliku 2?
Tim
Tak czy inaczej, wszystko będzie dobrze, o ile dane wyjściowe będą pasować do „pożądanego wyjścia.csv”
Roboman1723,
Dodałem nową odpowiedź, która moim zdaniem jest łatwiejsza niż wszystkie inne odpowiedzi (w tym moja pierwsza odpowiedź). Możesz rozważyć zaakceptowanie tego, aby w przyszłości łatwo było znaleźć informacje.
don.joey

Odpowiedzi:

11

Tylko z awkpoleceniem:

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

Pobierz wiersz z pliku 1 i zapisz go w zmiennej lokalnej f1, a następnie wydrukuj wiersz, który jest zapisany, f1i na końcu wydrukuj pola trzecie ( $3) i czwarte ( ) $3z pliku 1, które są rozdzielone przecinkiem ,, i zmień OFS (separator pól wyjściowych [spacja przez default]) do przecinka ( ,).


Krótkie polecenie wyglądałoby tak:

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

wklej plik2, a następnie wytnij i wklej trzecią kolumnę do następnej ( -f3-) z pliku1.


Z awki paste(opcja A)

Poniższe polecenie kopiuje również dwie ostatnie kolumny ( C,D) z pliku1 na końcu każdej linii w pliku2:

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

Powyższe polecenie wklej zawartość pliku 2, następnie wydrukuj separator przecinka ( -d','), a następnie wklej dwa ostatnie pole ( NFjest indeksem ostatniego pola i $NFciągiem, którego jest indeksem NF. Podobnie $(NF-1)jak drugie pole przed ostatnim polem) z pliku 1, gdy indeks ten redefiniuje lub dzieli za pomocą przecinka ( -F',').

Z awki paste(opcja B)

To polecenie jest również takie samo jak powyżej ( $3i $4wskazuje na trzecie i czwarte pole każdej linii z pliku1):

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

Lub inne rozwiązanie z cutpoleceniem:

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

polecenie cut w powyższym poleceniu najpierw wytnij pierwsze pole ( -f1indeksowane przecinkiem ( -d.)) z file1 ( cut -d, -f1 file1), następnie wytnij i wklej drugie pole file2 ( cut -d, -f2 file2), a na koniec wytnij i wklej trzecią kolumnę ( -f3) do następnej ( -) z pliku1 ( cut -d, -f3- file1) ponownie.

To polecenie zwraca również ten sam wynik:

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

wklej drugie pole z pliku1 ( awk -F',' '{print $1}' file1), następnie wydrukuj przecinek ( -d,), następnie wklej drugą kolumnę z pliku2 ( awk -F',' '{print $2}' file2), w końcu wklej ponownie drugą i ostatnią kolumnę pliku1 ( awk -F',' '{print $3","$4}' file1).

αғsнιη
źródło
@ kasi możesz to zrobić przez sam awk. Patrz stackoverflow.com/a/14984673/3297613
Avinash Raj
9

Oto piękno (tak myślę):

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

Podzielone na etapy:

Krok 1. Zainstaluj csvkit:

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

Krok 2. Użyj polecenia łączyć z przecinkiem jako separatorem

join -t,

Krok 3. Podaj rzeczywiste kolumny, które chcesz. Zwróć uwagę, w jaki sposób podajesz go do pierwszej kolumny dwa razy, ponieważ jest to ta, na której faktycznie wykonywane jest łączenie (zachowanie domyślne join).

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

lub w skrócie:

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

Możesz przekierować to standardowe wyjście do pliku (pożądanego wyjścia), jeśli chcesz.

Zalety

Ta metoda ma kilka zalet w stosunku do innych proponowanych.

Przede wszystkim: wykonuje prawdziwe połączenie. Oznacza to, że można go również wykorzystać do bardziej złożonych danych. Na przykład bardzo łatwo jest wykonać złączenie w innym polu. Nie tylko patrzy na pozycję pola, ale tak naprawdę bierze pod uwagę kolumnę. W rzeczywistości działa z formatem danych (csv) i nie traktuje tego jak tekstu.

Po drugie, wykorzystuje bardzo potężny zestaw narzędzi csv, który pozwala również na a) wyświetlanie statystyk za pomocą jednego polecenia ( csvstats), b) sprawdzanie, czy dane są czyste ( csvclean), ale także przekształcanie ich w json, sql, a nawet ładowanie do pyton! Ten zestaw narzędzi jest szeroko stosowany w analizie danych do przygotowywania danych.

don.joey
źródło
Jeśli instalujesz na Ubuntu, może być konieczne zainstalowanie nagłówków programistycznych Python przed instalacją csvkit: sudo apt-get install python-dev python-pip python-setuptools build-essential- link
karel
Świetna odpowiedź, pracuję też na serwerze firmowym, więc instalacja zajmuje około tygodnia papierkowej roboty. Działa na moim komputerze!
Roboman1723,
+1 za pokazanie mi innego narzędzia do danych CSV. Oddzielne pytanie, ale czy znasz niezależnego autora raportów dla plików danych CSV?
Joe
@Joe, czy możesz bardziej szczegółowo określić, co masz na myśli, mówiąc o „pisarzu raportów”? Nie jestem pewien, czy rozumiem, co masz na myśli.
don.joey
Zadałem
Joe
7

Oto kolejny piękny. Myślę, że jak dotąd jest to najłatwiejsza ze wszystkich sugestii.

csvtool pastecol 2 2 file1.csv file2.csv

Jeśli nie instalowałeś już csvtool w przeszłości, musisz to zrobić sudo apt-get install csvtool.

Z dokumentów:

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

Zamień zawartość kolumn, do których odwołuje się plik w pliku input.csv, na jedną z odpowiednich kolumn określonych w pliku update.csv.

Przykład:

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

Zwróć uwagę, jak w naszym przypadku zastępujemy drugie kolumny plików.

Przykłady

plik1.csv

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

plik2.csv

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

Łączenie dwóch plików:

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

Zasadniczo wklejasz drugą file2.csvkolumnę jako kolumnę 2 do file1.csv.

Pamiętaj, że działa to również w tym samym dokumencie. Jeśli chcesz zamienić dwie kolumny, możesz to zrobić, używając tego samego pliku co input.csv i update.vsc.

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A
don.joey
źródło
Bez wątpienia najbardziej elegancki.
Jacob Vlijm
2

Aby przenieść wybraną liczbę kolumn z jednego pliku do drugiego:

#!/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:]))

z dwóch plików:

plik_1

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

plik_2

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

Po ustawieniu cols = 1:

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

Ale kiedy ustawisz 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

Jak używać

Skopiuj go do pustego pliku, należy ustawić ścieżkę file1, file2a liczba kolumn, aby przenieść, zapisać go jako move.pyi uruchomić go przez:

python3 /path/to/move.py

W ten sposób można również dodać jedną lub więcej kolumn ze środka kolumn pliku źródłowego.

Jacob Vlijm
źródło
Chciałbym zobaczyć, jak używasz import csv.
don.joey
@ don.joey Dzięki za sugestię, na pewno ją przeanalizuję.
Jacob Vlijm
0

Inna metoda w pythonie poprzez moduł csv.

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))

Aby uruchomić powyższy skrypt,

python3 script.py file1 file2

Wynik:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
Avinash Raj
źródło