이전 필드에 일치하는 항목이 있으면 열을 가로로 결합합니다. 조인할 여러 열

이전 필드에 일치하는 항목이 있으면 열을 가로로 결합합니다. 조인할 여러 열

따라서 다음과 같은 일부 서명 마커(chr, start, end, chr, 별표, end, 겹치는 기본 쌍 수)가 포함된 삽입 히트가 포함된 파일이 있습니다.

    chr1    69744110    69793325    .   -1  -1  0
    chr1    82791976    82831348    chr1    82792114    82792615    501
    chr1    82791976    82831348    chr1    82816285    82817077    792
    chr1    82791976    82831348    chr1    82828015    82829891    1876
    chr1    88599340    88658398    .   -1  -1  0
    chr1    137772945   137830035   .   -1  -1  0
    chr1    137875312   137920590   .   -1  -1  0
    chr1    193433080   193446861   .   -1  -1  0
    chr10   26483800    26501370    chr10   26484794    26485295    501
    chr10   68069913    68089436    .   -1  -1  0
    chr10   95098349    95113967    .   -1  -1  0
    chr10   97310211    97335589    .   -1  -1  0
    chr10   111083097   111118237   chr10   111088928   111090274   1346
    chr10   117904141   117947090   chr10   117905334   117906320   986
    chr10   117904141   117947090   chr10   117918966   117919852   886
    chr10   117904141   117947090   chr10   117926867   117927368   501
    chr11   11521339    11587607    chr11   11523970    11524747    777
    chr11   11521339    11587607    chr11   11555497    11559868    4371
    chr11   11521339    11587607    chr11   11560639    11562128    1489
    chr11   11521339    11587607    chr11   11564617    11565370    753

그래서 필요한 것은 5열(column5/column5...), 6열(column6/column6...) 및 7열(column/column7)의 값을 연결하는 것입니다... 제가 첫 번째에 있다면 3열에 일치 항목이 있습니다. 4열도 보관하고 싶은데, 놓쳐도 괜찮습니다.

출력은 다음과 같아야 합니다.

    chr1    69744110    69793325    .   -1  -1  0
    chr1 82791976 82791976 chr1 82792114/82816285/82828015 82792615/82817077/82829891 501/792/1876
    chr1    88599340    88658398    .   -1  -1  0
    chr1    137772945   137830035   .   -1  -1  0
    chr1    137875312   137920590   .   -1  -1  0
    chr1    193433080   193446861   .   -1  -1  0
    chr10   26483800    26501370    chr10   26484794    26485295    501            (...)
    chr10   117904141   117947090   chr10 117905334/117918966/117926867 117906320/117919852/117927368   986/886/501
    (...)

여러 번 실험해 본 결과 내가 할 수 있는 최선의 방법은 다음과 같습니다.

    awk '{ k=$1 FS $2 FS $3;  a[k]=(k in a)? a[k]"/"$5 : $5 }
 END{ for(i in a) { 
          split(i,b,FS); b[5]=a[i]"\t"b[5]; r=""; 
          for(j=1;j<=NF;j++) { 
              r=(r!="")? r"\t"b[j] : b[j] 
          } 
          print r} 
    }' input.bed > output.bed

하지만 이렇게 하면 값이 손실되고 여러 열을 결합할 수 없습니다.

도와주세요?

편집하다:

새로운 시도:

    awk -F'\t' -v OFS='\t' '{
        if ($2 in a) {
            a[$2] = a[$2]";"$5;
            b[$2] = b[$2]";"$6;
        } else {
            a[$2] = $5;
            b[$2] = $6;
       }
    }
    END { for (i in a) print i, a[i], b[i] }' input.bed > output.bed

하지만 평가되지 않은 필드가 계속 손실됩니다.

답변1

awk를 사용하세요. 불행하게도 awk에는 배열 연결 기능이 내장되어 있지 않지만 gawk 온라인 매뉴얼에는 배열 연결을 작성하는 방법에 대한 예가 있습니다.

이것이 파일에 있는 경우 aggregate.awk(입력 파일이 탭으로 구분되어 있다고 가정합니다)

BEGIN {
    FS = OFS = "\t"
}

# ref https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html#Join-Function
function join(array, start, end, sep,    result, i)
{
    if (sep == "")
        sep = " "
    else if (sep == SUBSEP) # magic value
        sep = ""
    result = array[start]
    for (i = start + 1; i <= end; i++)
        result = result sep array[i]
    return result
}

function print_record() {
    last_line[5] = join(col5, 1, n, "/")
    last_line[6] = join(col6, 1, n, "/")
    last_line[7] = join(col7, 1, n, "/")
    print join(last_line, 1, NF, OFS)
}

{
    key = $1 OFS $2 OFS $3
}

key != prev_key {
    if (n > 0) {
        print_record()
    }
    delete col5
    delete col6
    delete col7
    n = 0
}

{
    n++
    col5[n] = $5
    col6[n] = $6
    col7[n] = $7
    prev_key = key
    split($0, last_line)
}

END {print_record()}

그런 다음 우리는 다음을 가집니다:

$ awk -f aggregate.awk input.bed
chr1    69744110        69793325        .       -1      -1      0
chr1    82791976        82831348        chr1    82792114/82816285/82828015      82792615/82817077/82829891      501/792/1876
chr1    88599340        88658398        .       -1      -1      0
chr1    137772945       137830035       .       -1      -1      0
chr1    137875312       137920590       .       -1      -1      0
chr1    193433080       193446861       .       -1      -1      0
chr10   26483800        26501370        chr10   26484794        26485295        501
chr10   68069913        68089436        .       -1      -1      0
chr10   95098349        95113967        .       -1      -1      0
chr10   97310211        97335589        .       -1      -1      0
chr10   111083097       111118237       chr10   111088928       111090274       1346
chr10   117904141       117947090       chr10   117905334/117918966/117926867   117906320/117919852/117927368   986/886/501
chr11   11521339        11587607        chr11   11523970/11555497/11560639/11564617     11524747/11559868/11562128/11565370     777/4371/1489/753

답변2

질문:

처음 3개 열에 일치하는 항목이 있으면 5,6,7열의 값을 연결합니다.

답변:

perl -lane 'if($.==1){@a=@F;next} if($F[0]eq$a[0]&&$F[1]eq$a[1]&&$F[2]eq$a[2]){$a[4].="/$F[4]";$a[5].="/$F[5]";$a[6].="/$F[6]";}else{for($i=0;$i<@a;$i++){printf "\t%s",$a[$i]};print"";@a=@F}END{for($i=0;$i<@a;$i++){printf "\t%s",$a[$i]};print""}' input.bed

산출:

    chr1    69744110        69793325        .       -1      -1      0
    chr1    82791976        82831348        chr1    82792114/82816285/82828015      82792615/82817077/82829891      501/792/1876
    chr1    88599340        88658398        .       -1      -1      0
    chr1    137772945       137830035       .       -1      -1      0
    chr1    137875312       137920590       .       -1      -1      0
    chr1    193433080       193446861       .       -1      -1      0
    chr10   26483800        26501370        chr10   26484794        26485295        501
    chr10   68069913        68089436        .       -1      -1      0
    chr10   95098349        95113967        .       -1      -1      0
    chr10   97310211        97335589        .       -1      -1      0
    chr10   111083097       111118237       chr10   111088928       111090274       1346
    chr10   117904141       117947090       chr10   117905334/117918966/117926867   117906320/117919852/117927368   986/886/501
    chr11   11521339        11587607        chr11   11523970/11555497/11560639/11564617     11524747/11559868/11562128/11565370     777/4371/1489/753

노트:

더 짧거나 더 우아한 솔루션이 있을 수 있습니다.

관련 정보