GNU/Linux >> Belajar Linux >  >> Linux

Bandingkan Dua Kolom File Yang Berbeda Dan Cetak Jika Cocok?

Saya menggunakan Solaris 10 dan opsi grep yang melibatkan -f tidak berfungsi.

Saya memiliki dua file yang dipisahkan pipa:

file1:

abc|123|BNY|apple|
cab|234|cyx|orange|
def|kumar|pki|bird|

berkas 2:

abc|123|
kumar|pki|
cab|234

Saya ingin membandingkan dua kolom pertama file2 dengan file1 (mencari seluruh isi file1 dalam dua kolom pertama) jika mereka cocok mencetak baris file1 yang cocok. Kemudian cari baris kedua dari file 2 dan seterusnya.

Hasil yang Diharapkan:

abc|123|BNY|apple|
cab|234|cyx|orange|

File yang saya miliki sangat besar, berisi sekitar 400.000 baris, jadi saya ingin mempercepat eksekusi.

Jawaban yang Diterima:

Untuk inilah awk dirancang:

$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|

Penjelasan

  • -F'|' :menyetel pemisah bidang ke | .
  • NR==FNR :NR adalah nomor baris input saat ini dan FNR nomor baris file saat ini. Keduanya akan sama hanya saat file pertama sedang dibaca.
  • c[$1$2]++; next :jika ini adalah file pertama, simpan dua kolom pertama di c Himpunan. Kemudian, lewati ke baris berikutnya sehingga ini hanya diterapkan pada file pertama.

  • c[$1$2]>0 :blok else hanya akan dieksekusi jika ini adalah file kedua jadi kami memeriksa apakah kolom 1 dan 2 dari file ini sudah terlihat (c[$1$2]>0 ) dan jika sudah, kami mencetak baris. Dalam awk , tindakan default adalah mencetak baris jadi jika c[$1$2]>0 benar, garis akan dicetak.

Atau, karena Anda menandai dengan Perl:

perl -e 'open(A, "file2"); while(<A>){/.+?|[^|]+/ && $k{$&}++};
         while(<>){/.+?|[^|]+/ && do{print if defined($k{$&})}}' file1

Penjelasan

Baris pertama akan membuka file2 , baca semuanya hingga | ke-2 (.+?|[^|]+ ) dan simpan itu ($& adalah hasil dari operator pertandingan terakhir) di %k hash.

Baris kedua memproses file1, menggunakan regex yang sama untuk mengekstrak dua kolom pertama dan mencetak baris jika kolom tersebut didefinisikan dalam %k hash.

Kedua pendekatan di atas perlu menahan 2 kolom pertama file2 di memori. Seharusnya tidak menjadi masalah jika Anda hanya memiliki beberapa ratus ribu baris tetapi jika ya, Anda dapat melakukan sesuatu seperti

cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done

Tapi itu akan lebih lambat.

Terkait:Salin semua program &file yang diinstal di hard disk (yang memiliki Windows 7) 32 bit dan klon/transfer ke komputer lain yang memiliki Windows 7 64 bit?
Linux
  1. Bagaimana membandingkan tiga file di Linux menggunakan alat diff3

  2. Cetak Garis Antara (dan Termasuk) Dua Pola?

  3. Cetak Dua File Dalam Dua Kolom?

  1. Cetak Garis Pencocokan Dan Garis Ke-N Dari Garis Yang Cocok?

  2. Bagaimana Membandingkan Dua File Dan Kemudian Menambahkan Baris Yang Tidak Cocok Sebagian?

  3. Garis Umum Antara Dua File?

  1. Bandingkan File dan Folder Secara Grafis di Linux Dengan Meld

  2. Cetak Garis Antara (dan Tidak Termasuk) Dua Pola?

  3. Bagaimana cara mengarahkan stderr dan stdout ke file berbeda di baris yang sama dalam skrip?