2011-02-11 33 views
5

Tôi muốn hợp nhất hai tệp theo nội dung của các cột thứ 2 của chúng.unix: hợp nhất 2 tệp bằng cách sử dụng các cột thứ hai

Tập 1:

"4742" "209220_at"  2.60700394801826 
"104" "209396_s_at" 2.60651442103297 
"749" "202409_at"  2.59424724783704 
"4168" "209875_s_at" 2.58773204877464 
"3973" "1431_at"  2.52832098784342 
"1826" "207201_s_at" 2.41685345240968 

File2:

"653" "1431_at"  2.14595534191867 
"1109" "207201_s_at" 2.13777517447307 
"353" "212531_at"  2.12706340284672 
"381" "206535_at"  2.11456707231618 
"1846" "204534_at"  2.10919474441178 

Để có cuối cùng:

"3973" "1431_at"  2.52832098784342 "653" "1431_at"  2.14595534191867 
"1826" "207201_s_at" 2.41685345240968 "1109" "207201_s_at" 2.13777517447307 

Tôi đã thử comm, diff, một số che khuất awk một lót mà không bất kỳ thành công nào. Bất kỳ trợ giúp nào được đánh giá cao. Ben

Trả lời

2
awk ' 
    # store the first file, indexed by col2 
    NR==FNR {f1[$2] = $0; next} 
    # output only if file1 contains file2's col2 
    ($2 in f1) {print f1[$2], $0} 
' file1 file2 
+2

lưu ý rằng thao tác này sẽ lưu toàn bộ tệp1 vào bộ nhớ, vì vậy bạn có thể muốn đặt tệp nhỏ hơn thành 'file1' –

0

Nếu tệp nhỏ, hãy viết chương trình bằng ngôn ngữ kịch bản (Perl, Python và Ruby là tất cả lựa chọn tốt), lần đầu tiên đọc băm có khóa là cột thứ hai, sau đó đọc qua tệp thứ hai và sử dụng tra cứu băm để giải quyết những gì (nếu có) có thể được tham gia.

Nếu tệp lớn sau đó cho mỗi tệp hoán đổi cột đầu tiên và cột thứ hai, hãy chuyển chúng qua tiện ích sắp xếp unix và sau đó kết hợp ngôn ngữ kịch bản (sắp xếp lại cột) hai tệp được sắp xếp.

5

Bạn có thể thực hiện điều đó bằng cách kết hợp các lệnh sortjoin. Cách tiếp cận đơn giản là

join -j2 <(sort -k2 file1) <(sort -k2 file2) 

nhưng hiển thị hơi khác so với bạn đang tìm kiếm. Nó chỉ cho thấy sự phổ biến tham gia lĩnh vực và sau đó các trường còn lại từ mỗi tập tin

"1431_at" "3973" 2.52832098784342 "653" 2.14595534191867 
"207201_s_at" "1826" 2.41685345240968 "1109" 2.13777517447307 

Nếu bạn cần định dạng chính xác như bạn thấy, sau đó bạn sẽ cần phải nói cho join để đầu ra theo cách mà

join -o 1.1,1.2,1.3,2.1,2.2,2.3 -j2 <(sort -k2 file1) <(sort -k2 file2) 

trong đó -o chấp nhận danh sách các thông số FILENUM.FIELDNUM.

Lưu ý rằng cú pháp <() Tôi đang sử dụng không phải là POSIX sh, vì vậy bạn nên sắp xếp thành một tệp tạm thời nếu bạn cần cú pháp sh POSIX.

+0

nếu bạn đang sử dụng phiên bản nào đó của bash, bạn cũng có thể viết: 'tham gia -j2 <(tập tin loại -k2 {1,2})' –

+0

Ngoại trừ việc không cung cấp tham gia với hai bộ đầu vào riêng biệt. – jamessan

0
awk 'FNR==NR{a[$2]=$0} NR>FNR && ($2 in a){ print $0,a[$2] } ' file2 file1 
Các vấn đề liên quan