Thay thế các mục phù hợp trong một cột của tệp bằng một cột khác từ một tệp khác


8

Tôi có hai tệp được phân tách bằng tab trông như sau:

tập tin1:

NC_008146.1     WP_011558474.1  1155234 1156286 44173
NC_008146.1     WP_011558475.1  1156298 1156807 12
NC_008146.1     WP_011558476.1  1156804 1157820 -3
NC_008705.1     WP_011558474.1  1159543 1160595 42748
NC_008705.1     WP_011558475.1  1160607 1161116 12
NC_008705.1     WP_011558476.1  1161113 1162129 -3
NC_009077.1     WP_011559727.1  2481079 2481633 8
NC_009077.1     WP_011854835.1  1163068 1164120 42559
NC_009077.1     WP_011854836.1  1164127 1164636 7

tập tin 2:

NC_008146.1     GCF_000014165.1_ASM1416v1_protein.faa
NC_008705.1     GCF_000015405.1_ASM1540v1_protein.faa
NC_009077.1     GCF_000016005.1_ASM1600v1_protein.faa

Tôi muốn khớp cột 1 của tệp1 với tệp2 và thay thế nó bằng mục nhập cột 2 tương ứng của tệp 2. Đầu ra sẽ như thế này:

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

Có vẻ như bạn cũng có thể quan tâm đến trang web chị em của chúng tôi: Tin sinh học .
terdon

Cảm ơn bạn đã liên kết @terdon!
BhushanDhamale

Câu trả lời:


14

Bạn có thể làm điều này rất dễ dàng với awk:

$ awk 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa WP_011558474.1 1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa WP_011558475.1 1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa WP_011558476.1 1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa WP_011558474.1 1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa WP_011558475.1 1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa WP_011558476.1 1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa WP_011559727.1 2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa WP_011854835.1 1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa WP_011854836.1 1164127 1164636 7

Hoặc, vì nó trông giống như một tệp được phân tách bằng tab:

$ awk -vOFS="\t" 'NR==FNR{a[$1]=$2; next}{$1=a[$1]; print}' file2 file1
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa   WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa   WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa   WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa   WP_011854836.1  1164127 1164636 7

Điều này giả định rằng mỗi NC_*id RefSeq ( ) file1có một mục tương ứng file2.

Giải trình

  • NR==FNR: NR là số dòng hiện tại, FNR là số dòng của tệp hiện tại. Cả hai sẽ giống hệt nhau trong khi tệp 1 (ở đây file2) đang được đọc.
  • a[$1]=$2; next: nếu đây là tệp đầu tiên (xem bên trên), hãy lưu trường thứ 2 trong một mảng có khóa là trường thứ nhất. Sau đó, chuyển sang nextdòng. Điều này đảm bảo khối tiếp theo không được thực thi cho tệp đầu tiên.
  • {$1=a[$1]; print}: bây giờ, trong tệp thứ hai, đặt trường thứ 1 thành bất kỳ giá trị nào được lưu trong mảng acho trường thứ 1 (vì vậy, giá trị được liên kết từ file2) và in dòng kết quả.

1
NR == FNRkhông hoạt động chính xác khi tập tin đầu tiên trống. Xem điều này và câu trả lời liên quan cho một cách giải quyết
iruvar

3
@iruvar sẽ không có gì hoạt động tốt nếu tập tin đầu tiên trống, vì vậy tôi không thực sự hiểu tại sao điều đó có liên quan. Toàn bộ vấn đề ở đây là kết hợp dữ liệu từ hai tệp. Nếu một trong hai tập tin trống, toàn bộ bài tập là vô nghĩa.
terdon

xin lỗi tôi nên nói trong trường hợp cụ thể này file2và không file1trống rỗng. Hành vi lành mạnh khi file2trống là để báo cáo nội dung của file1. Vấn đề với NR == FNRlà mã được liên kết với nó thực thi trên nội dung file1khi file2nào trống
iruvar

3
@iruvar không có hành vi lành mạnh ở đây nếu một trong hai tệp trống. Đó là những gì tôi đang nói :) Vì vậy, cố gắng giải quyết vụ việc đó một cách duyên dáng là vô nghĩa. Và, trong mọi trường hợp, khi một trong hai tệp trống ở đây, không có gì được in. Mà thực sự có vẻ giống như cách tiếp cận rõ ràng nhất, tôi thà không có dữ liệu hơn dữ liệu sai.
terdon

17

Không cần awk, giả sử các tệp được sắp xếp, bạn có thể sử dụng coreutils tham gia:

join -o '2.2 1.2 1.3 1.4 1.5' file1 file2

Đầu ra:

GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7

Nếu các tệp của bạn không được sắp xếp, bạn có thể sắp xếp chúng trước ( sort file1 > file1.sorted; sort file2 > file2.sorted) và sau đó sử dụng lệnh ở trên hoặc nếu shell của bạn hỗ trợ <()cấu trúc (bash does), bạn có thể thực hiện:

join -o '2.2 1.2 1.3 1.4 1.5' <(sort file1) <(sort file2)

0

Đã thử nghiệm với lệnh dưới đây và hoạt động tốt

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done

đầu ra

for i in `awk '{print $1}' f2`; do k=`awk -v i="$i" '$1==i {print $2}' f2`;sed  "/$i/s/$i/$k/g" f1 >f3;done


GCF_000014165.1_ASM1416v1_protein.faa     WP_011558474.1  1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558475.1  1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa     WP_011558476.1  1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558474.1  1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558475.1  1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa     WP_011558476.1  1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa     WP_011559727.1  2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854835.1  1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa     WP_011854836.1  1164127 1164636 7
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.