파일 1의 열 2와 3과 파일 2의 열 4와 5를 비교하는 방법

파일 1의 열 2와 3과 파일 2의 열 4와 5를 비교하는 방법

탭으로 구분된 파일 1이 있습니다.

NC_025345       4569   4950   KX838946.2      
NC_025345       16546   17066   KJ641660.1      
NC_025345       11996   12085   KX932454.2

파일 2:

NC_025345.1     RefSeq  gene    5690    7513    .       +       .       ID=gene-NZ82_gp4;Dbxref=GeneID:20964334;Name=NZ82_gp4;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp4
NC_025345.1     RefSeq  gene    8016    10046   .       +       .       ID=gene-NZ82_gp5;Dbxref=GeneID:20964335;Name=NZ82_gp5;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp5
NC_025345.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6

파일 1의 열 2와 3을 파일 2의 열 4와 5와 비교하고 싶습니다. 파일 1의 열 2와 열 3이 파일 2의 열 4와 열 5 사이에 겹치거나 해당하는 경우 다음 출력을 사용하여 파일 1과 파일 2의 전체 행을 새 파일로 병합하고 싶습니다.

NC_025345       11996   12085   KX932454.2     NC_025345.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6

답변1

이것은 가장 효율적인 awk스크립트가 아닐 수도 있습니다.

awk '{
  if (NR==FNR) {
    l[NR]=$0
    a[NR]=$2
    b[NR]=$3
  }
  else if (a[FNR]>=$4 && b[FNR]<=$5) {
    print l[FNR],$0
  }
}' file1 file2 > newfile

첫 번째 파일( )을 읽을 때 NR==FNR전체 행 $0과 필드를 $2배열의 인덱스(레코드 번호) 에 저장합니다 $3. NR두 번째 파일을 읽으면 배열의 값 ab지정된 인덱스 FNR(파일의 레코드 번호) 에 있는 값이 필드 sum 과 $4비교됩니다 $5.

배열 값이 범위 내에 있으면 이전 행과 현재 행을 인쇄합니다. 출력은 새 파일에 기록됩니다 newfile.

답변2

다음과 같이 수행할 수 있습니다. 먼저 파일을 함께 붙여넣은 다음 awk를 실행하여 필요한 줄을 필터링합니다.

$ nf1=$(<file1 awk '{print NF;exit}') 

$ paste file1 file2 | awk -vnf1="$nf1" '$(4+nf1)<=$2 && $3<=$(5+nf1)'

답변3

#!/usr/bin/perl

use strict;

my $f1=shift;
open(F1,"<",$f1) || die "Couldn't open $f1: $!\n";

my $f2=shift;
open(F2,"<",$f2) || die "Couldn't open $f2: $!\n";

until (eof(F1) || eof(F2)) {
  my @a = split /\t/,<F1>;
  my @b = split /\t/,<F2>;
  chomp($a[@a-1]);

  # note: perl arrays start from 0, not 1
  print join("\t",@a, @b) if (($a[1] >= $b[3]) && ($a[2] <= $b[4]));
}

그러면 두 개의 파일 이름 인수가 파일 핸들 F1및 로 열립니다. F2두 파일 중 하나를 열 수 없으면 오류 메시지와 함께 종료됩니다.

그런 다음, 그 중 어느 것도 EOF(파일 끝)에 도달하지 않지만 다음을 수행합니다.

  • 각 파일 핸들에서 한 번에 한 줄씩 별도의 배열( @aF1 및 @bF2의 경우)로 읽습니다.

    이 함수는 배열의 마지막 요소에서 후행 개행 문자( )를 제거 chomp()하여 배열 연결의 출력 줄 중간에 개행이 나타나는 것을 방지합니다.\n@a

  • 배열이 조건($a[1]>=$b[3] 및 $a[2]<=$b[4])을 충족하는 경우 탭 문자를 필드 구분 기호로 사용하여 두 배열을 하나의 출력 라인으로 인쇄합니다. .

예를 들어 다른 이름으로 저장하고 ibk.pl실행 가능하게 만든 후 chmod +x ibk.pl다음과 같이 실행합니다.

$ ./ibk.pl file1 file2 
NC_025345       11996   12085   KX932454.2      NC_025345.1     RefSeq  gene    10337   16933   .       +       .       ID=gene-NZ82_gp6;Dbxref=GeneID:20964336;Name=NZ82_gp6;gbkey=Gene;gene_biotype=protein_coding;locus_tag=NZ82_gp6

관련 정보