awk/sed를 사용하여 특정 필드에서 문자열 제거

awk/sed를 사용하여 특정 필드에서 문자열 제거

다음과 같은 파일(80,000줄 이상)이 있습니다.

chr1    GTF2GFF chromosome  1   249213345   .   .   .   ID=chr1;Name=chr1
chr1    GTF2GFF gene    11874   14408   .   +   .   ID=DDX11L1;Note=unknown;Name=DDX11L1
chr1    GTF2GFF exon    11874   12227   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF exon    12613   12721   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF exon    13221   14408   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF gene    14362   29370   .   -   .   ID=WASH7P;Note=unknown;Name=WASH7P
chr1    GTF2GFF exon    14362   14829   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    14970   15038   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    15796   15947   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    16607   16765   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    16858   17055   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17233   17368   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17606   17742   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17915   18061   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    18268   18366   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    24738   24891   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    29321   29370   .   -   .   Parent=NR_024540
chr1    GTF2GFF gene    34611   36081   .   -   .   ID=FAM138A;Note=unknown;Name=FAM138A
chr1    GTF2GFF exon    34611   35174   .   -   .   Parent=NR_026818
chr1    GTF2GFF exon    35277   35481   .   -   .   Parent=NR_026818

세 번째 필드에서 "gene"이 포함된 행만 추출하고 ID 값(예: DDX11L1)만 포함하도록 9번째 필드를 재정렬하고 싶습니다. 원하는 출력은 다음과 같습니다.

chr1    11874   14408   DDX11L1    .       +
chr1    14362   29370   WASH7P      .       -
chr1    34611   36081   FAM138A    .       -

awk를 사용하면 필수 필드를 쉽게 얻을 수 있습니다.

head -20 genes.gff3 | awk '$3=="gene" {print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}'
chr1    11874   14408   ID=DDX11L1;Note=unknown;Name=DDX11L1    .       +
chr1    14362   29370   ID=WASH7P;Note=unknown;Name=WASH7P      .       -
chr1    34611   36081   ID=FAM138A;Note=unknown;Name=FAM138A    .       -

하지만 ID 값을 가져오는 데 문제가 있습니다. 나는 그것을 sed로 파이핑하려고 시도했습니다.

head -20 genes.gff3 | awk '$3=="gene" {print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}' | sed 's/\(^.+\t\)ID=\(\w+\).+\(\t.+$\)/\1\2\3/g'

그리고 gsub

head -20 genes.gff3 | awk '$3=="gene" {gsub(/\(^.+\t\)ID=\(\w+\).+\(\t.+$\)/, "\1\2\3", $9); print $1 "\t" $4 "\t" $5 "\t" $9"\t" $6 "\t" $7}' 

하지만 결과는 awk만 사용한 것과 같습니다. ID 값을 추출하는 방법은 무엇입니까? 나는 해결책에 매우 가깝다고 느낀다.

건배.

답변1

함수의 필드 구분 기호 split는 정규식이므로 =OR로 분할 할 수 있습니다 ;. 당신이 알고 있었다면$9 시작"ID="를 사용하면

awk -v OFS='\t' '
    $3 == "gene" {
        split($9, id, /[=;]/)
        print $1, $4, $5, id[2], $6, $7
    }
' genes.gff3

"ID="가 반드시 필드 시작 부분에 있지 않은 경우에도 수행해야 할 작업이 있습니다.

awk -v OFS='\t' '
    $3 == "gene" {
        id = ""
        len = split($9, f, /[=;]/)
        for (i=1; i<len; i++) {
            if (f[i] == "ID") {
                id = f[i+1]
                break
            }
        }
        print $1, $4, $5, id, $6, $7    
    }
' genes.gff3

답변2

당신은 할 수split분야 및 용도substr통과:

split($9, a, ";")
print substr(a[1], 4)

awk 인덱스는 에서 시작됩니다 1.

또 다른 옵션은 입력 필드 구분 기호( FS)를 수정하는 것입니다. FS공백입니다. 기본값은 ""입니다. 여기에도 특수 효과가 있습니다.선행 및 후행 공백 무시.

print $1, \t, ...또한, 사용 이나 변형 대신 탭으로 설정할 수도 있습니다 .printfOFS


예:

FS 수정:

awk -F" +|;|=" '

$3 == "gene" {
    printf("%s\t%s\t%s\t%s\t%s\t%s\t\n",
    $1, $4, $5, $10, $6, $7);
}
' data.file

분할 사용:

awk '
$3 == "gene" {
    split($9, a, ";")
    printf("%s\t%s\t%s\t%s\t%s\t%s\t\n",
    $1, $4, $5, substr(a[1], 3), $6, $7);
}
' data.file

OFS 및 FS:

출력 필드 구분 기호( OFS)를 탭으로 사용하고 FSawk에서 재정의합니다. 또한 FS탭을 포함하도록 업데이트되었습니다.

awk '
BEGIN {
    FS="[ \t]+|;|="
    OFS="\t"
}
$3 == "gene" {
    print $1, $4, $5, $10, $6, $7
}

' data.file

또한보십시오그룹 열기 변수 및 특수 변수,.

고크 매뉴얼– 이는 일반적으로 awk의 gawk 확장일 때 나타납니다.

답변3

awk다음은 및 사용에 대한 명시적인 요청에도 불구하고 게시할 수 있는 Bash 솔루션입니다 sed.

show_genes()
{
    local filename="$1"
    while read -ra larr; do
        if [[ ${larr[2]} = gene ]]; then
            larr[8]="${larr[8]%%;*}"
            larr[8]="${larr[8]#ID=}"
            printf '%s\n' "${larr[*]}"
        fi
    done < "$filename"
}

용법:show_genes /path/to/some/file.txt

예제 출력:

[rany$] cat data.txt
romosome  1   249213345   .   .   .   ID=chr1;Name=chr1
chr1    GTF2GFF gene    11874   14408   .   +   .   ID=DDX11L1;Note=unknown;Name=DDX11L1
chr1    GTF2GFF exon    11874   12227   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF exon    12613   12721   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF exon    13221   14408   .   +   .   Parent=NR_046018_1
chr1    GTF2GFF gene    14362   29370   .   -   .   ID=WASH7P;Note=unknown;Name=WASH7P
chr1    GTF2GFF exon    14362   14829   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    14970   15038   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    15796   15947   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    16607   16765   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    16858   17055   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17233   17368   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17606   17742   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    17915   18061   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    18268   18366   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    24738   24891   .   -   .   Parent=NR_024540
chr1    GTF2GFF exon    29321   29370   .   -   .   Parent=NR_024540
chr1    GTF2GFF gene    34611   36081   .   -   .   ID=FAM138A;Note=unknown;Name=FAM138A
chr1    GTF2GFF exon    34611   35174   .   -   .   Parent=NR_026818
chr1    GTF2GFF exon    35277   35481   .   -   .   Parent=NR_026818
[rany$] show_genes data.txt
chr1 GTF2GFF gene 11874 14408 . + . DDX11L1
chr1 GTF2GFF gene 14362 29370 . - . WASH7P
chr1 GTF2GFF gene 34611 36081 . - . FAM138A
[rany$]

답변4

짧은 커피 브레이크 답변

perl -ne 's/\t.*?\tgene//            #remove \t F2 \t gene
      and s/\S*\tID=(.*?);.*/$1/     #remove \t Fn \t ID=.... keeping the id
      and print'  file

관련 정보