如何在awk或sed中使用正则表达式,找到DNA序列中的所有均聚物?

时间:2015-05-25 15:55:41

标签: regex awk sed bioinformatics gawk

背景

均聚物是具有连续相同碱基的DNA的亚序列,如AAAAAAA。 python中用于提取它的示例:

import re
DNA = "ACCCGGGTTTAACCGGACCCAA"
homopolymers = re.findall('A+|T+|C+|G+', DNA)
print homopolymers
['A', 'CCC', 'GGG', 'TTT', 'AA', 'CC', 'GG', 'A', 'CCC', 'AA']

我的努力

我制作了一个解决问题的gawk脚本,但没有使用正则表达式:

echo "ACCCGGGTTTAACCGGACCCAA" | gawk '
BEGIN{
  FS=""
}
{
  homopolymer = $1;
  base = $1;
  for(i=2; i<=NF; i++){
    if($i == base){
      homopolymer = homopolymer""base;
    }else{
      print homopolymer;
      homopolymer = $i;
      base = $i;
    }
  }
  print homopolymer;
}'

输出

A
CCC
GGG
TTT
AA
CC
GG
A
CCC
AA

问题

如何在awk或sed中使用正则表达式,得到相同的结果?

2 个答案:

答案 0 :(得分:6)

grep -o会在一行中找到你:

echo "ACCCGGGTTTAACCGGACCCAA"| grep -ioE '([A-Z])\1*'
A
CCC
GGG
TTT
AA
CC
GG
A
CCC
AA

<强>解释

([A-Z])   # matches and captures a letter in matched group #1
\1*       # matches 0 or more of captured group #1 using back-reference \1

sed不是最好的工具,但是因为OP要求它:

echo "ACCCGGGTTTAACCGGACCCAA" | sed -r 's/([A-Z])\1*/&\n/g'
A
CCC
GGG
TTT
AA
CC
GG
A
CCC
AA

PS:这是gnu-sed。

答案 1 :(得分:1)

尝试使用拆分并进行比较。

echo "ACCCGGGTTTAACCGGACCCAA" | awk '{ split($0, chars, "")
  for (i=1; i <= length($0); i++) {
    if (chars[i]!=chars[i+1])
    {
      printf("%s\n", chars[i])
    }
   else
   { 
     printf("%s", chars[i])
   }
  }
 }' 

A
CCC
GGG
TTT
AA
CC
GG
A
CCC
AA

<强>说明

split方法将您发送的单行字符串分为awk,并在数组chars []中分隔每个字符。现在,我们遍历整个数组并检查char是否等于下一个if (chars[i]!=chars[i+1])然后,如果它相等,我们只打印char,然后等待下一个。如果下一个不同,我们只打印基本字符,\n表示换行符。