如何删除相同的主题并影响 awk 中的所有其他行

如何删除相同的主题并影响 awk 中的所有其他行

我有一个包含两个 DNA 序列(具有相同碱基数)的文件:

>seq1
NNNNNAGAATGGGTGANNATTTCCCNN
>seq2
NNAGGGTCCCAATCCNNAACCTTNNNN

N我想删除一个或两个序列中包含 a 的位置。在此示例中,结果将是:

>seq1
AGAATGGGTGATTTC
>seq2
GTCCCAATCCACCTT

到目前为止,我已经写了,但它只是逐个删除序列N

awk '/^>/ {printf("%s%s\t",(N>0?"\n":""),$0);N++;next;} {printf("%s",$0);} END {printf("\n");}' < input | sed 's/N//g' | tr "\t" "\n" > output

有人知道该怎么做吗?

生物背景:FASTA 格式设计了如何在文本文件中写入 DNA 序列。它的第一行是序列名称,并以符号 开头>。第二行是 DNA 序列本身。在我的例子中,我有 2 个序列,所以我有 4 行

答案1

这是一个快速技巧:

#!/bin/sh
awk '
    function strip( n ) {
            i = index(body[n], "N")
            while ( i > 0 ) {
                    body[1] = substr(body[1], 0, i-1) substr(body[1], i+1)
                    body[2] = substr(body[2], 0, i-1) substr(body[2], i+1)
                    i = index(body[n], "N")
            }
    }

    /^>/ { 
            N++
            label[N] = $0
            next
    }
    {
            body[N] = $0
    }
    END {
            if ( N != 2 ) {
                    print "Incorrect number of entries" >"/dev/stderr"
                    exit 1
            }
            strip(1)
            strip(2)
            print label[1]
            print body[1]
            print label[2]
            print body[2]
    }
' dna >output

文件DNA是:

>seq1
NNNNNAGAATGGGTGANNATTTCCCNN
>seq2
NNAGGGTCCCAATCCNNAACCTTNNNN

文件输出为:

>seq1
AGAATGGGTGATTTC
>seq2
GTCCCAATCCACCTT

我认为这符合你的要求。

答案2

$ cat tst.awk
{ lines[NR] = $0 }
!/>/ {
    numChars = length($0)
    for ( charPos=1; charPos<=numChars; charPos++)  {
        char = substr($0,charPos,1)
        if ( char == "N" ) {
            badPoss[charPos]
        }
    }
}
END {
    for ( lineNr=1; lineNr<=NR; lineNr++ ) {
        line = lines[lineNr]
        if ( line ~ />/ ) {
            out = line
        }
        else {
            out = ""
            numChars = length(line)
            for ( charPos=1; charPos<=numChars; charPos++)  {
                if ( !(charPos in badPoss) ) {
                    char = substr(line,charPos,1)
                    out = out char
                }
            }
        }
        print out
    }
}

$ awk -f tst.awk file
>seq1
AGAATGGGTGATTTC
>seq2
GTCCCAATCCACCTT

上面假设您的输入文件足够小以适合内存。如果没有,您可以通过分两次读取文件来执行相同的操作,第一次创建badPoss[],第二次使用它:

$ cat tst.awk
NR==FNR {
    if ( !/>/ ) {
        numChars = length($0)
        for ( charPos=1; charPos<=numChars; charPos++)  {
            char = substr($0,charPos,1)
            if ( char == "N" ) {
                badPoss[charPos]
            }
        }
    }
    next
}
{
    if ( />/ ) {
        out = $0
    }
    else {
        out = ""
        numChars = length($0)
        for ( charPos=1; charPos<=numChars; charPos++)  {
            if ( !(charPos in badPoss) ) {
                char = substr($0,charPos,1)
                out = out char
            }
        }
    }
    print out
}

$ awk -f tst.awk file file
>seq1
AGAATGGGTGATTTC
>seq2
GTCCCAATCCACCTT

答案3

使用awk,您可以使用两遍方法进行如图所示的操作。在第一遍中,我们构建屏蔽位(存储“N”的位)。

awk -v OFS= -v _PASS1_=1 '
_PASS1_ {
  if ( /^>/ ) next
  if (n in a)
    for (i=1; i<=n; i++)
     a[i] *= substr($0,i,1) != "N"
  else {
    t=$0
    gsub(/N/,0,t)
    gsub(/[^0]/,1,t)
    gsub(/./,"&"FS,t)
    n=split(t,a)
  }
  next
}
!/^>/{
  t=$0; $0=""
  for (i=1; i<=n; i++)
    $i = a[i] ? substr(t,i,1) : ""
}1
' file _PASS1_=0 file

另一种方法是转置输入文件,如果在转置行的任何位置看到“N”,则该行标记为“0”,否则标记为“1”。然后我们再进行一次转置并获得掩码位,然后对输入的 rasta 文件进行操作以获得所需的 o/p。

这使用GNU sed+BSD rs+awk.

rs是用于转置的重塑器实用程序。

sed -n '/^>/!s/./& /pg' file |
rs -T | 
sed '/N/s/.*/0/;t;c 1' |
rs -T | 
awk -v OFS= '
NR==1{n=1+split($0,a);next}
!/^>/{
  t=$0
  for (i=$0=""; ++i in a;)
    $i = substr(t, a[i] ? i:n, 1)
}1' - file

输出:-

>seq1
AGAATGGGTGATTTC
>seq2
GTCCCAATCCACCTT

答案4

我们可以使用sed(所示的GNU sed)代码以两遍方式来完成此操作。

sed -E '
  /\n/{
    s///;$q;h;d
  }

/^>/{
  N;s/.*\n//
  y/ATCGN/11110/
  G
  s/(.*).$/&\1/
  /^(.*)\n\1$/{s/$/\n/;D;}

  s/^/\n/;ta
  :a;/\n$/D
  s/\n0(.*)\n1/0\n\10\n/;ta
  s/\n.(.*)\n(.)/1\n\1\2\n/;ta
}' file |
sed -E '
  1{h;d;}
  /^>/b
  G;s/^/\n/
  :mask
    s/\n.(.*)\n0/\n\1\n/
    s/\n(.)(.*)\n1/\1\n\2\n/
    s/\n\n$//
  tmask
' - file

相关内容