Câu trả lời:
Câu trả lời dưới đây dựa trên một câu hỏi và trả lời tương tự trong SO với một số sửa đổi có liên quan:
$ 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
Ý tưởng là tạo ra một bản đồ băm với chỉ mục và sử dụng nó làm từ điển.
Đối với câu hỏi thứ 2 bạn đã hỏi trong nhận xét của mình ( điều gì sẽ được thay đổi nếu cột thứ hai file1.txt
sẽ là cột thứ sáu ):
Nếu tệp đầu vào sẽ như file1b.txt
sau:
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
Lệnh sau sẽ thực hiện:
$ 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
Tôi biết bạn đã nói awk
, nhưng có một join
lệnh cho mục đích này ...
{
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
Nó là đủ với join
lệnh đầu tiên nếu nó không dành cho dòng này:
item4 platD
Về cơ bản lệnh nói: tham gia dựa trên cột thứ hai của tệp đầu tiên ( -1 2
) và cột đầu tiên của tệp thứ hai ( -2 1
) và xuất cột đầu tiên của tệp đầu tiên và cột thứ hai của tệp thứ hai ( -o 1.1,2.2
). Điều đó chỉ hiển thị các dòng mà ghép nối. Lệnh tham gia thứ hai nói gần như giống nhau, nhưng nó cho biết hiển thị các dòng từ tệp đầu tiên không thể ghép nối ( -v 1
) và xuất cột đầu tiên của tệp đầu tiên và cột thứ hai của tệp đầu tiên ( -o 1.1,1.2
). Sau đó, chúng tôi sắp xếp đầu ra của cả hai kết hợp. sort -k 1
có nghĩa là sắp xếp dựa trên cột đầu tiên và sort -k 2
có nghĩa là sắp xếp dựa trên cột thứ hai. Điều quan trọng là sắp xếp các tệp dựa trên cột tham gia trước khi chuyển chúng đến join
.
Bây giờ, tôi đã viết cách sắp xếp hai lần, vì tôi không muốn xả các thư mục của mình bằng các tệp nếu tôi có thể giúp nó. Tuy nhiên, như David Foerster đã nói, tùy thuộc vào kích thước của các tệp, bạn có thể muốn sắp xếp các tệp và lưu chúng trước để không phải chờ đợi để sắp xếp hai lần. Để đưa ra ý tưởng về kích thước, đây là thời gian để sắp xếp 1 triệu và 10 triệu dòng trên máy tính của tôi:
$ 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
Đó là 1,5 giây cho 1 triệu dòng và 19 giây cho 10 triệu dòng.
%E
ở định dạng thời gian) ít thú vị hơn để đo hiệu suất tính toán. Thời gian CPU của người dùng ( %U
hoặc đơn giản là một TIMEFORMAT
biến không đặt ) sẽ có ý nghĩa hơn nhiều.
%U
.