Awk bunun için tasarlandı:
$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|
açıklama
-F'|'
: alan ayırıcısını olarak ayarlar |
.
NR==FNR
: NR geçerli giriş satırı numarası ve FNR geçerli dosyanın satır numarasıdır. İkisi yalnızca 1. dosya okunurken eşit olacaktır.
c[$1$2]++; next
: bu 1. dosyaysa, c
dizideki ilk iki alanı kaydedin . Ardından, yalnızca 1. dosyaya uygulanacak şekilde bir sonraki satıra geçin.
c[$1$2]>0
: else bloğu yalnızca bu ikinci dosyaysa yürütülür, bu nedenle bu dosyanın 1 ve 2 alanlarının önceden görülüp görülmediğini kontrol ederiz ( c[$1$2]>0
) ve eğer olduysa satırı yazdırırız. İçinde awk
, varsayılan eylem satırı yazdırmaktır, böylece c[$1$2]>0
doğruysa, satır yazdırılır.
Alternatif olarak, Perl ile etiketlediğinizden:
perl -e 'open(A, "file2"); while(<A>){/.+?\|[^|]+/ && $k{$&}++};
while(<>){/.+?\|[^|]+/ && do{print if defined($k{$&})}}' file1
açıklama
İlk satır açılacak file2
, 2. |
( .+?\|[^|]+
) 'ye kadar olan her şeyi okuyacak ve bunu ( $&
son maç operatörünün sonucu) %k
karmaya kaydedecektir .
İkinci satır dosya1'i işler, ilk iki sütunu ayıklamak ve bu sütunlar %k
karma içinde tanımlanmışsa satırı yazdırmak için aynı normal ifadeyi kullanır .
Yukarıdaki her iki yaklaşımın da dosya2'nin ilk 2 sütununu bellekte tutması gerekecektir. Sadece birkaç yüz bin hattınız varsa bu bir sorun olmamalı, ancak eğer böyle bir şey yapabilirsiniz
cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done
Ama bu daha yavaş olacak.