Inilah yang dirancang untuk awk:
$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|
Penjelasan
-F'|'
: mengatur 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 1 sedang dibaca.
c[$1$2]++; next
: jika ini adalah file ke-1, simpan kedua bidang ke-1 dalam c
array. Kemudian, lewati ke baris berikutnya sehingga ini hanya diterapkan pada file ke-1.
c[$1$2]>0
: blok else hanya akan dieksekusi jika ini adalah file kedua jadi kami memeriksa apakah bidang 1 dan 2 dari file ini sudah terlihat ( c[$1$2]>0
) dan jika sudah, kami mencetak baris. Dalam awk
, tindakan standar adalah mencetak garis jadi jika c[$1$2]>0
benar, garis akan dicetak.
Atau, karena Anda ditandai dengan Perl:
perl -e 'open(A, "file2"); while(<A>){/.+?\|[^|]+/ && $k{$&}++};
while(<>){/.+?\|[^|]+/ && do{print if defined($k{$&})}}' file1
Penjelasan
Baris pertama akan terbuka file2
, membaca semuanya hingga ke-2 |
( .+?\|[^|]+
) dan menyimpannya (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 dalam memori. Itu seharusnya tidak menjadi masalah jika Anda hanya memiliki beberapa ratus ribu baris tetapi jika ya, Anda bisa melakukan sesuatu seperti
cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done
Tapi itu akan lebih lambat.