첫 번째 행에서 하위 문자열과 일치하는 탭으로 구분된 열을 제거합니다.

첫 번째 행에서 하위 문자열과 일치하는 탭으로 구분된 열을 제거합니다.

제목(첫 번째 행)에 "_HET" 문자열이 포함된 텍스트 파일에서 탭으로 구분된 모든 열을 제거하고 싶습니다. 입력 텍스트 파일은 다음과 같습니다.

rs36810213_HET   rs2438689   rs70927523570_HET   rs54666437   ...
1                0           2                   0
0                1           0                   1
2                0           1                   1
...              ...         ...                 ...

출력 텍스트 파일은 다음과 같아야 합니다.

rs2438689   rs54666437   ...
0           0
1           1
0           1
...         ...

내가 사용하는 코드는 아무것도 삭제하지 않습니다.

#!/bin/bash

path="/data/folder"

awk -v OFS='\t' '

NR==1{
    for (i=1;i<=NF;i++)
        if ($i=="_HET") {
            n=i-1
            m=NF-(i==NF)
        }
    }

{
    for(i=1;i<=NF;i+=1+(i==n))
        printf "%s%s",$i,i==m?ORS:OFS
}

' $path/input.txt >> $path/output.txt

이 코드를 수정하는 방법에 대한 제안 사항이 있습니까? 감사합니다!

답변1

awk -F '\t' -f script.awk file

script.awk어디

BEGIN { OFS = FS }

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        if ($i !~ /_HET/)
            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
}

keep먼저 첫 번째 줄의 헤더를 구문 분석하고 연관 배열 에 유지하려는 헤더를 기억하세요 .

그런 다음 각 행에 대해 유지하려는 필드에서만 현재 레코드(행)를 다시 만들고 인쇄합니다.

현재 필드 구분 기호의 행을 배열로 (재)분할한 fields다음 비워서 이를 수행합니다.모두필드( 를 사용하면 $0 = ""재설정됨 NF)를 선택하고 마지막으로 배열 fields의 키인 필드 만 할당합니다 keep.

어떤 사람들은 재치 있는 말을 하는 것을 좋아합니다.

awk -F '\t' -v OFS='\t' 'FNR==1{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1}{n=split($0,f,FS);$0=j="";for(i=1;i<=n;++i)if(i in k)$(++j)=f[i]}1' file

귀하의 코드를 정확하게 따르지는 않았지만 :th 필드를 string 과 비교 $i=="_HET"합니다 . 이 필드의 값이i_HET정확히 _HET(귀하의 제목 필드가 없습니다.)


완전히 다른 접근 방식:

cut -f "$( awk -F '\t' -v OFS="," '{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1;$0="";for(i in k)$(++j)=i;print;exit}' file )" file

awk신청서

BEGIN { OFS = "," }

{
    for (i = 1; i <= NF; ++i)
        if ($i !~ /_HET/)
            keep[i] = 1

    $0 = ""

    for (i in keep)
        $(++j) = i

    print
    exit
}

출력 없음콘텐츠원하는 열 수이지만 해당 열 번호를 쉼표로 구분된 문자열로 출력합니다. 그런 다음 이 문자열은 cut데이터에서 열을 제거하는 데 사용됩니다 .

답변2

Perl을 사용하여 다음과 같이 이 작업을 수행할 수 있습니다.

$ perl -F'/\t/' -pale '$"="\t";
    $. == 1 and @A = grep { $F[$_] !~ /_HET/ } 0 .. $#F;
    $_ = "@F[@A]";
' input.tsv

관련 정보