Tambahkan kolom dari satu .csv ke file .csv lainnya

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

Output.csv yang diinginkan

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

Saya sudah mencoba menggunakan "gabung" dan "tempel" tetapi tidak berhasil. Apakah ada perintah bash untuk melakukan ini? Kolom "A" sama di kedua .csvfile.

Roboman1723
sumber
Jadi Anda meminta untuk menyalin kolom B ke File 1? Atau kolom C dan D ke file2?
Tim
Apa pun caranya akan baik-baik saja selama keluarannya cocok dengan "yang diinginkan .putput.csv"
Roboman1723
Saya telah menambahkan jawaban baru yang, saya pikir, lebih mudah daripada semua jawaban lainnya (termasuk jawaban pertama saya). Anda mungkin ingin mempertimbangkan untuk menerimanya sehingga untuk referensi di masa mendatang informasi tersebut mudah ditemukan.
don.joey

Jawaban:

11

Dengan hanya awkperintah:

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

Dapatkan baris dari file1 dan simpan ke dalam variabel lokal f1, lalu cetak baris yang disimpan di dalam f1dan akhirnya cetak bidang ketiga ( $3) dan sebagainya ( $3) dari file1 yang dipisahkan dengan koma ,sama sekali, dan ubah OFS (pemisah bidang keluaran [spasi oleh default]) ke koma ( ,).


Perintah singkatnya akan seperti ini:

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

tempel file2, lalu potong dan tempel kolom ketiga ke berikutnya ( -f3-) dari file1.


Dengan awkdan paste(opsi A)

Perintah di bawah ini juga menyalin dua kolom terakhir ( C,D) dari file1 di akhir setiap baris di file2:

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

Perintah di atas, tempel konten file2 lalu cetak koma pembatas ( -d',') kemudian tempelkan dua bidang terakhir ( NFadalah indeks bidang terakhir dan $NFadalah string yang indeksnya NF. Jadi $(NF-1)adalah bidang kedua sebelum bidang terakhir) dari file1 ketika indeks tersebut mendefinisikan kembali atau membelah dengan penonton koma ( -F',').

Dengan awkdan paste(opsi B)

Perintah ini juga sama seperti di atas ( $3dan $4menunjuk ke bidang ketiga dan keempat dari setiap baris dari file1):

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

Atau solusi lain dengan cutperintah:

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

perintah cut di perintah di atas pertama memotong bidang pertama ( -f1yang diindeks dengan koma pembatas ( -d.)) dari file1 ( cut -d, -f1 file1), kemudian memotong dan menempelkan bidang kedua file2 ( cut -d, -f2 file2) dan akhirnya memotong dan menempelkan kolom ketiga ( -f3) ke yang berikutnya ( -) dari file1 ( cut -d, -f3- file1) lagi.

Perintah ini juga mengembalikan hasil yang sama:

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

tempel bidang kedua dari file1 ( awk -F',' '{print $1}' file1) lalu cetak koma ( -d,), lalu tempel kolom kedua dari file2 ( awk -F',' '{print $2}' file2), akhirnya tempel kembali kolom kedua dan terakhir dari file1 ( awk -F',' '{print $3","$4}' file1).

αғsнιη
sumber
@ kasi Anda bisa melakukan ini melalui awk itu sendiri. Lihat stackoverflow.com/a/14984673/3297613
Avinash Raj
9

Inilah keindahan (saya pikir):

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

Rusak dalam beberapa langkah:

Langkah 1. Instal csvkit:

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

Langkah 2. Gunakan perintah join dengan koma sebagai pemisah

join -t,

Langkah 3. Masukkan kolom yang sebenarnya Anda inginkan. Perhatikan bagaimana Anda mengumpankannya kolom pertama dua kali, karena itu yang benar-benar dilakukan oleh join (perilaku default join).

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

atau singkat:

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

Anda dapat mengarahkan output standar itu ke file (inginkanOutput) jika diinginkan.

Keuntungan

Metode ini memiliki beberapa keunggulan dibandingkan yang lain yang diusulkan.

Pertama dan terpenting: ia melakukan gabung yang nyata. Itu berarti dapat digunakan untuk data yang lebih kompleks juga. Sangat mudah untuk melakukan gabung di bidang lain, misalnya. Itu tidak hanya melihat posisi lapangan, tetapi benar-benar mempertimbangkan kolom. Ini benar-benar berfungsi dengan format data (csv) dan tidak memperlakukannya seperti teks.

Kedua, ia menggunakan toolkit csv yang sangat kuat yang juga memungkinkan Anda untuk a) menampilkan statistik dengan satu perintah ( csvstats), b) memeriksa apakah datanya bersih ( csvclean), tetapi juga untuk mengubahnya menjadi json, menjadi sql, atau bahkan memuatnya ke dalam ular sanca! Toolkit ini banyak digunakan dalam ilmu data untuk persiapan data.

jangan
sumber
Jika Anda menginstal di Ubuntu Anda mungkin perlu menginstal header pengembangan Python sebelum menginstal csvkit: sudo apt-get install python-dev python-pip python-setuptools build-essential- link
karel
Jawaban yang luar biasa juga, saya sedang mengerjakan server perusahaan sehingga menginstal barang membutuhkan waktu sekitar satu minggu dari pekerjaan kertas. Bekerja pada mesin saya sekalipun!
Roboman1723
+1 untuk menunjukkan kepada saya alat lain untuk data CSV. Pisahkan pertanyaan, tetapi apakah Anda tahu penulis laporan mandiri untuk file data CSV?
Joe
@Apakah Anda dapat lebih spesifik tentang apa yang Anda maksudkan ketika berbicara tentang 'penulis laporan'? Saya tidak yakin saya mengerti maksud Anda.
don.joey
Saya memposting pertanyaan terpisah di unix.stackexchange.com/questions/170199/...
Joe
7

Ini satu lagi yang indah. Saya pikir ini adalah saran yang paling mudah, sejauh ini.

csvtool pastecol 2 2 file1.csv file2.csv

Jika Anda belum menginstal csvtool di masa lalu, Anda harus melakukannya sudo apt-get install csvtool.

Dari dokumen:

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

Ganti konten kolom yang direferensikan oleh dalam file input.csv dengan salah satu kolom yang sesuai yang ditentukan oleh di update.csv.

Contoh:

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

Perhatikan bagaimana dalam kasus kami, kami mengganti kolom kedua file.

Contohnya

file1.csv

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

file2.csv

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

Menggabungkan dua file:

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

Apa yang pada dasarnya Anda lakukan adalah menempelkan kolom dua file2.csvsebagai kolom 2 di file1.csv.

Perhatikan bahwa ini juga berfungsi pada dokumen yang sama. Jika Anda ingin menukar dua kolom, Anda dapat melakukannya dengan menggunakan file yang sama dengan input.csv dan update.vsc.

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A
jangan
sumber
Tidak diragukan lagi yang paling elegan.
Jacob Vlijm
2

Untuk memindahkan jumlah kolom yang dipilih dari satu file ke file lain:

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

dari dua file:

file_1

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

file_2

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

Ketika Anda mengatur cols = 1:

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

Tetapi ketika Anda mengatur 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

Cara Penggunaan

Salin ke file kosong, setel path ke file1, file2dan jumlah kolom untuk dipindahkan, simpan sebagai move.pydan jalankan dengan:

python3 /path/to/move.py

Juga dimungkinkan untuk menambahkan satu atau lebih kolom dari tengah kolom file sumber dengan cara ini.

Yakub Vlijm
sumber
Akan sangat senang melihat Anda menggunakan import csv.
don.joey
@ don.joey Terima kasih atas sarannya, pasti akan memeriksanya.
Jacob Vlijm
0

Metode lain dalam python melalui modul 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))

Untuk menjalankan skrip di atas,

python3 script.py file1 file2

Keluaran:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D
Avinash Raj
sumber