/ / как да използваме регулярна експресия в awk или sed, за да намерите всички хомополимери в последователността на ДНК? - regex, awk, sed, биоинформатика, gawk

как да използвате регулярен израз в awk или sed, за да намерите всички хомополимери в ДНК последователността? - regex, awk, sed, bioinformatics, gawk

Заден план

Хомополимерите са под-последователност на ДНК с последователни идентични бази, като 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;
}"

продукция

А CCC GGG TTT АА CC GG А CCC АА

въпрос

как мога да използвам регулярни изрази в awk или sed, получавайки същия резултат?

Отговори:

6 за отговор № 1

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 не е най-добрият инструмент за това, но тъй като ОП поиска:

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

PS: Това е gnu-sed.


1 за отговор № 2

Опитайте да използвате сплит и просто да сравнявате.

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

A
CCC
GGG
TTT
AA
CC
GG
A
CCC
AA

ОБЯСНЕНИЕ

Методът за разделяне разделя едноредовия низ, който изпращате на awk, и разделя всеки символ в масивите от масиви []. Сега минаваме през целия масив и проверяваме дали знака е равен на следващия if (chars[i]!=chars[i+1]) и след това, ако е равно, просто отпечатваме знака и чакаме следващото. Ако следващият е различен, просто отпечатваме основната карта, a n какво означава нов ред.