Yanıtlar:
Aşağıdaki cevap, bazı ilgili değişikliklerle SO'daki benzer bir Soru ve Cevaplara dayanmaktadır :
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Fikir, indeksli bir karma harita oluşturmak ve bunu sözlük olarak kullanmaktır.
Yorumunuzda sorduğunuz 2. soru için ( ikinci sütunu file1.txt
altıncı sütun olacaksa nelerin değiştirilmesi gerekir ):
Giriş dosyası aşağıdaki gibi olacaksa file1b.txt
:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
Aşağıdaki komut bunu yapar:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Söylediğini biliyorum awk
, ama join
bu amaçla bir emir var ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
join
Bu satır olmasaydı ilk komutla yeterli olurdu :
item4 platD
Komut temelde şöyle der: ilk dosyanın ( -1 2
) ikinci sütununa ve ikinci dosyanın ( ) ilk sütununa dayalı olarak birleşin ve ilk dosyanın ilk sütununu ve ikinci dosyanın ( -2 1
) ikinci sütununu çıktılayın -o 1.1,2.2
. Bu sadece eşleşen satırları gösterir. İkinci birleştirme komutu hemen hemen aynı şeyi söyler, ancak ilk dosyadan eşleştirilemeyen satırları ( -v 1
) gösterir ve ilk dosyanın ilk sütununu ve ilk dosyanın ( -o 1.1,1.2
) ikinci sütununu çıkarır . Sonra her ikisinin de çıktısını sıraladık. sort -k 1
ilk sütuna sort -k 2
göre sıralama, ikincisine göre sıralama anlamına gelir. Dosyaları geçirmeden önce birleştirme sütununa göre sıralamak önemlidir join
.
Şimdi, sıralamayı iki kez yazdım, çünkü yardımcı olabilirsem dizinlerimi dosyalarla doldurmak istemiyorum. Ancak, David Foerster'in dediği gibi, dosyaların boyutuna bağlı olarak, dosyaları sıralamak ve her birini iki kez sıralamak için beklemek zorunda kalmadan önce kaydetmek isteyebilirsiniz. Boyutlar hakkında bir fikir vermek için, bilgisayarımda 1 milyon ve 10 milyon satır sıralamanın zamanı geldi:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Bu 1 milyon satır için 1.5 saniye ve 10 milyon satır için 19 saniyedir.
%E
zaman formatında) hesaplama performansını ölçmek için daha az ilgi çekicidir. Kullanıcı modu CPU süresi ( %U
veya basitçe ayarlanmamış bir TIMEFORMAT
değişken) çok daha anlamlı olacaktır.
%U
.