헤더 하위 문자열과 일치하는 텍스트 파일에서 열 추출

헤더 하위 문자열과 일치하는 텍스트 파일에서 열 추출

헤더(첫 번째 줄)가 다른 텍스트 파일 "strings"에 나열된 하위 문자열과 일치하는 텍스트 파일 "columns.txt"에서 탭으로 구분된 열을 추출하고 싶습니다.
"columns.txt"는 다음과 같습니다.

A   B   C   D   E   F   rs243_A   rs546_G   rs987_T   rs025_C   ...
A   B   C   D   E   F   0         0         0         1         ...
A   B   C   D   E   F   1         1         2         2         ...
A   B   C   D   E   F   0         1         2         0         ...
... ... ... ... ... ... ...       ...       ...       ...       ...

"strings.txt"는 다음과 같습니다:

rs243
rs987  
...

출력 텍스트 파일은 "columns.txt"에서 열 1-6을 복사한 다음 "strings.txt"에 지정된 추출된 모든 열(탭으로 구분)을 추가해야 합니다. 출력 파일 "output.txt"는 다음과 같아야 합니다.

A   B   C   D   E   F   rs243   rs987   ...
A   B   C   D   E   F   0       0       ...
A   B   C   D   E   F   1       2       ...
A   B   C   D   E   F   0       2       ...
... ... ... ... ... ... ...     ...     ...

내가 사용하고 있는 코드는 원하는 대로 "output.txt"에 열 1-6을 인쇄하지만 추출된 열을 추가하지는 않습니다.

awk -F '\t' -f /data/p_00614/ABCD/scripts/extract.awk /data/strings.txt /data/columns.txt > /data/output.txt

"extract.awk" 사용:

BEGIN { OFS = FS }

FNR == NR {
    sub("_.*", "", $1)
    columns[$1] = 1
    next
}

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        if (i <= 6 || $i in columns)
            keep[i] = 1
}

{
    nf = split($0, fields, FS)
    $0 = ""
    j = 0

    for (i = 1; i <= nf; ++i)
        if (i in keep)
            $(++j) = fields[i]

    print 
}

내 생각에는

sub("_.*", "", $1)

작동하지 않습니다. "_.*"아마도 시작하는 모든 하위 문자열을 잘라내지는 않고 _정확히 일치하는 부분만 잘라내는 것 같습니다. 이 문제를 해결하는 방법에 대한 제안이 있으십니까? 감사합니다!

답변1

이것은 내가 제공한 코드의 버그입니다.귀하의 질문 중 하나에 대한 이전 답변(지금은 수정되었습니다). _.*에서 읽는 문자열에서는 비트를 제거하지 말고 strings.txt에서 읽는 데이터에서는 비트 를 제거해야 합니다 columns.txt.

수정된 스크립트:

BEGIN { OFS = FS }

FNR == NR {
    columns[$1] = 1
    next
}

FNR == 1 {
    for (i = 1; i <= NF; ++i) {
        sub("_.*", "", $i)
        if (i <= 6 || $i in columns)
            keep[i] = 1
    }
}

{
    nf = split($0, fields, FS)
    $0 = ""
    j = 0

    for (i = 1; i <= nf; ++i)
        if (i in keep)
            $(++j) = fields[i]

    print 
}

질문에 있는 내용 FNR == NR과 블록이 약간 변경되었음을 확인하세요 .FNR == 1

관련 정보