Заден план
Хомополимерите са под-последователност на ДНК с последователни идентични бази, като 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 за отговор № 1grep -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
какво означава нов ред.