Saya menggunakan Solaris 10 dan opsi grep yang melibatkan -f tidak bekerja.
Saya memiliki dua file yang dipisahkan pipa:
file1:
abc|123|BNY|apple|
cab|234|cyx|orange|
def|kumar|pki|bird|
file 2:
abc|123|
kumar|pki|
cab|234
Saya ingin membandingkan dua kolom pertama dari file2 dengan file1 (mencari seluruh isi file1 dalam dua kolom pertama) jika mereka cocok mencetak baris yang cocok dari file1. Kemudian cari baris kedua file 2 dan seterusnya.
Output 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.
shell-script
text-processing
perl
pengguna68365
sumber
sumber
grep
, itu di bawah/usr/sfw/bin/ggrep
. stackoverflow.com/questions/15259882/…Jawaban:
Inilah yang dirancang untuk awk:
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 dalamc
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. Dalamawk
, tindakan standar adalah mencetak garis jadi jikac[$1$2]>0
benar, garis akan dicetak.Atau, karena Anda ditandai dengan Perl:
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
Tapi itu akan lebih lambat.
sumber
file2
ke dalam memori?awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0'
adalah versi yang lebih pendek.file2
memiliki baris rangkap?kupikir
adalah apa yang kamu cari. Itu harus efisien, tetapi saya tidak yakin itu akan seakurat yang Anda inginkan. Jika
abc|123
(misalnya) ditemukan garis dalamfile1
kolom yang berbeda, garis itu akan dicetak juga. Jika Anda dapat menjamin bahwa ini tidak akan pernah terjadi, kalimat di atas akan berfungsi.sumber
Jika Anda ingin memikirkan masalah dalam SQL like way, maka Anda pasti harus mencoba alat bernama ' q ':
Lebih jelas dan mudah dipahami jika Anda terbiasa dengan query SQL.
sumber
sumber