두 번째 파일의 패턴 일치를 기반으로 첫 번째 파일의 필드 매핑

두 번째 파일의 패턴 일치를 기반으로 첫 번째 파일의 필드 매핑

두 개의 탭으로 구분된 파일이 있고 파일 1의 첫 번째 열에 있는 텍스트를 다음과 같이 변환해야 합니다.어느파일의 2번째 줄에 있는 위치입니다. 일치 후 파일 1에서 일치하는 줄의 두 번째 열 내용을 파일 2의 일치하는 줄 끝까지 인쇄하고 싶습니다(아래 예).

나는 이것이 awk를 사용하여 거의 확실하게 수행될 수 있다는 것을 알고 있지만 awk 또는 sed에 그다지 능숙하지 않으며 여기에서 관련 질문을 검색하고 해당 스크립트를 적용하려고 시도하는 데 성공하지 못했습니다. 어떤 조언이라도 대단히 감사하겠습니다.

파일 1

protein_1.p1     note "PJD5F7, match to databaseID=64575, (species X)";
protein_1.p2     note "PJD5F7, match to databaseID=64575, (species X)";
protein_3.p1     note "PA5F9H, match to databaseID=93689, (species W)";
protein_4.p1     note "Q7GT5J, match to databaseID=89045, (species Y)";
protein_4.p3     note "YE6G3L, match to databaseID=44968, (species Z)";

파일 2

chromosome_1    programID   transcript_id "protein_1.p1"; parent "protein_1";
chromosome_1    programID   transcript_id "protein_1.p2"; parent "protein_1";
chromosome_1    programID   transcript_id "protein_2.p1"; parent "protein_2";
chromosome_1    programID   transcript_id "protein_2.p2"; parent "protein_2";
chromosome_1    programID   transcript_id "protein_3.p1"; parent "protein_3";
chromosome_1    programID   transcript_id "protein_4.p1"; parent "protein_4";
chromosome_1    programID   transcript_id "protein_4.p2"; parent "protein_4";
chromosome_1    programID   transcript_id "protein_4.p3"; parent "protein_4";

원하는 출력

chromosome_1    programID   transcript_id "protein_1.p1"; parent "protein_1"; note "PJD5F7, match to databaseID=64575, (species X)";
chromosome_1    programID   transcript_id "protein_1.p2"; parent "protein_1"; note "PJD5F7, match to databaseID=64575, (species X)";
chromosome_1    programID   transcript_id "protein_2.p1"; parent "protein_2";
chromosome_1    programID   transcript_id "protein_2.p2"; parent "protein_2";
chromosome_1    programID   transcript_id "protein_3.p1"; parent "protein_3"; note "PA5F9H, match to databaseID=93689, (species W)";
chromosome_1    programID   transcript_id "protein_4.p1"; parent "protein_4"; note "Q7GT5J, match to databaseID=89045, (species Y)";
chromosome_1    programID   transcript_id "protein_4.p2"; parent "protein_4";
chromosome_1    programID   transcript_id "protein_4.p3"; parent "protein_4"; note "YE6G3L, match to databaseID=44968, (species Z)";

답변1

file1을 구문 분석 하고 $2값( )을 키( $1)에 매핑한 다음 file2행()의 일부가 키와 일치 $3하면 구문 분석하고 값을 행에 추가할 수 있습니다 .

BEGIN {OFS = FS = "\t"}
FNR == NR {arr[$1] = $2; next}
{for (x in arr) if ($3 ~ x) {$0 = $0 " " arr[x]; break}}
{print}

이는 귀하의 예에 대한 올바른 결과를 인쇄하지만 여러 가지 이유로 원하는 결과가 아닙니다. 첫 번째는 , 등 다양한 상황에서 실패할 수 있다는 것 protein_1.p1입니다 protein_1.p11. 두 번째 이유는 성능입니다. file2의 각 줄에 대한 시간은 일정하지 않지만 크기는 ~입니다 file1.


따라서 위의 스크립트를 수정해야 합니다. 단백질 문자열과 일치하도록 정규식을 정의할 수 있습니다. 이렇게 하면 일치가 충분히 엄격해지고 두 번째 구문 분석에서 시간은 배열 크기가 아닌 필드의 정규식 일치에 따라 달라집니다.

BEGIN {OFS = FS = "\t"; re = "\\<protein_[[:digit:]]+.p[[:digit:]]+\\>"}
FNR == NR {if ($1 ~ re) arr[$1] = $2; next}
match($3, re) {$0 = $0 " " arr[substr($3,RSTART,RLENGTH)]}
{print}

노트:

  • re: "단백질_" 뒤에 하나 이상의 숫자, ".p", 그리고 하나 이상의 숫자가 모두 이러한 내부 단어 경계 내에 있습니다. 도트는 문자 그대로입니다. 단어 문자는 [:alnum:]이므로 _나머지는 경계입니다.
  • 또한 의 첫 번째 필드에 대해 온전성 검사가 수행됩니다 file1.
  • a가 발견 되면 match()내장 변수는 일치하는 문자열의 인덱스와 길이를 RSTART보유하며 RLENGTH이 하위 문자열은 해싱에 사용됩니다.

용법:

> awk -f tst.awk file1 file2
chromosome_1    programID   transcript_id "protein_1.p1"; parent "protein_1"; note "PJD5F7, match to databaseID=64575, (species X)";
chromosome_1    programID   transcript_id "protein_1.p2"; parent "protein_1"; note "PJD5F7, match to databaseID=64575, (species X)";
chromosome_1    programID   transcript_id "protein_2.p1"; parent "protein_2"; 
chromosome_1    programID   transcript_id "protein_2.p2"; parent "protein_2"; 
chromosome_1    programID   transcript_id "protein_3.p1"; parent "protein_3"; note "PA5F9H, match to databaseID=93689, (species W)";
chromosome_1    programID   transcript_id "protein_4.p1"; parent "protein_4"; note "Q7GT5J, match to databaseID=89045, (species Y)";
chromosome_1    programID   transcript_id "protein_4.p2"; parent "protein_4"; 
chromosome_1    programID   transcript_id "protein_4.p3"; parent "protein_4"; note "YE6G3L, match to databaseID=44968, (species Z)";

관련 정보