Mendapatkan Penampang dari Dua File CSV

1

Saya memiliki dua file CSV yang sedang saya kerjakan. Satu sangat besar, dengan sekitar 200.000 baris. Yang lain jauh lebih kecil, memiliki sekitar 12.000 baris. Keduanya sesuai dengan format nama yang sama, dan alamat email (semuanya sah di sini, jangan khawatir). Pada dasarnya saya mencoba untuk mendapatkan hanya sebagian dari daftar kedua dengan menghapus semua nilai yang saat ini ada di file yang lebih besar.

Jadi, Daftar A memiliki ~ 200k baris, dan Daftar B memiliki ~ 12k. Daftar ini sedikit tumpang tindih, dan saya ingin menghapus semua entri dari Daftar B jika mereka juga ada di Daftar A, meninggalkan saya dengan nilai-nilai baru dan unik hanya di Daftar B. Saya punya beberapa kesempatan yang saya inginkan. bisa menggunakan. Open Office dimuat di mesin ini, bersama dengan MySQL (kueri tidak masalah).

Apa cara termudah untuk membuat CSV ketiga dengan persimpangan data?

Sampson
sumber

Jawaban:

4

Dari baris perintah Linux / Unix / Mac:

sort file1 file2 | uniq -d | sort file2 - | uniq -u

Penjelasan:

Ini hanya mengembalikan baris-baris di file2 yang tidak persis cocok dengan baris apa pun di file1.

Tangga:

  1. sort file1 file2: Menggabungkan file1 dan file2 bersama-sama, mengurutkannya, dan mencetaknya ke stdout. Perhatikan bahwa duplikat akan terdaftar di baris yang berdekatan (dua kali berturut-turut) setelah pengurutan.
  2. uniq -d: Mengambil output dari perintah sebelumnya dan mencetak hanya baris yang merupakan duplikat .
  3. sort file2 -: Menggabungkan file2 asli dan output dari perintah sebelumnya (stdout, yang diwakili oleh nama file " - "hyphen), dan mencetak hasilnya ke stdout. Selain itu, setiap item dalam file2 yang juga di file1 akan digandakan (terdaftar dua kali berturut-turut) di output.
  4. uniq -u: Mengambil output dari perintah sebelumnya dan hanya mencetak item yang tidak digandakan (dengan kata lain, hanya mencetak item yang tidak terdaftar dua kali berturut-turut).

Gotcha yang mungkin:

Ini mengasumsikan bahwa setiap baris yang diberikan dalam file1 sama persis baris yang sesuai dalam file2. Jika, misalnya, file1 dan file2 memiliki email yang sama tetapi dengan huruf besar berbeda; atau jika file1 memiliki nama "Jon Sampson" sementara file2 memiliki alamat email yang sama dengan nama "Jonathan Sampson", mereka tidak akan dianggap duplikat.

Anda dapat mengontrol ini dengan melakukan pra-pemrosesan file untuk menghapus semuanya kecuali alamat email, dan selanjutnya, kecilkan alamat emailnya. Perintah Unix cut dan tr dapat membantu dalam kasus ini. Atau Anda bisa beralih ke SQL untuk skenario yang lebih kompleks.

Ukuran file:

File 200.000 baris dan satu dari 12.000 baris tidak terlalu besar. Saya menghasilkan file dengan ukuran yang sama menggunakan /usr/share/dict/words file di MacBook Pro saya dan menguji perintah di atas; butuh waktu kurang dari 5 detik untuk berjalan.

Nate
sumber
2

Nate telah memberi Anda jawaban yang sangat bagus, tetapi ada singkat lebih jauh dari baris perintah Linux / Unix / Mac:

join -t# -v2 <(sort file1.csv) <(sort file2.csv) > result.csv

Peringatan:

  • Pertanyaan aslinya adalah tentang menggabungkan seluruh baris. Satu-satunya cara yang bisa saya pikirkan
    menekan join Kebutuhan untuk membagi, adalah untuk mendefinisikan pembatas bidang sebagai karakter yang tidak digunakan di salah satu file ( # dalam contoh saya). Jelek, saya tahu.

  • File input harus diurutkan pada kolom gabungan. Anda dapat melakukan ini dalam satu baris (lihat di atas) tetapi itu hanya akan bekerja di bash. Kerang lain memiliki sintaks yang berbeda untuk ini.

Jika file input Anda diurutkan:

join -t# -v2 file1.csv file2.csv > result.csv

Untuk Windows ada port asli bergabung .

Ludwig Weinzierl
sumber
1
Wow! Saya tidak tahu join. Anda belajar sesuatu yang baru setiap hari.
Nate
Bagaimana saya meneruskan output ke CSV ketiga?
Sampson
Hmmm ... ini sepertinya memberi saya baris dari file2 yang cocok dengan baris dari file1. Dia perlu mendapatkan garis yang tidak cocok. Apakah saya melewatkan sesuatu?
Nate
Maaf, -a2 adalah gabung luar kanan. Jika Anda hanya ingin garis yang tidak adil itu -v.
Ludwig Weinzierl
1
Tampak hebat; Saya akan menguji ini sebentar.
Sampson