varrendo uma sequência e emitindo uma sub-sequência

3

Eu estou procurando um forro para isso, se for possível. Eu tenho uma sequência como essa

CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG

Eu quero obter a saída onde eu escaneio a base da seqüência por base e, em seguida, tirar 20 pb disso. SO a saída deve ser algo como isto

CCGGTCTCTTCCGGTTCTGT
CGGTCTCTTCCGGTTCTGTC
GGTCTCTTCCGGTTCTGTCT

e assim por diante .. O comprimento deve ser sempre de 20 pb

Eu escrevi um código perl e funcionou. Procurando por um forro, se alguém pode ajudar usando awk ou sed ??

while(<>){
    chomp;
    for my $i(0..length($_)){
        my $str = substr($_,$i,20);
        next if(length($str) < 20);
        print $str,"\n";
    }

}

Deixe-me saber

    
por user3138373 05.01.2016 / 18:39

5 respostas

1

Se você já conhece o Perl, por que não usá-lo? Perl se destaca no one-liners:

$ perl -F'' -lane 'for($i=0;$i<=$#F-20;$i++){print @F[$i..$i+20]}' file
CCGGTCTCTTCCGGTTCTGTC
CGGTCTCTTCCGGTTCTGTCT
GGTCTCTTCCGGTTCTGTCTT
GTCTCTTCCGGTTCTGTCTTT
TCTCTTCCGGTTCTGTCTTTT
CTCTTCCGGTTCTGTCTTTTC
TCTTCCGGTTCTGTCTTTTCG
CTTCCGGTTCTGTCTTTTCGC
TTCCGGTTCTGTCTTTTCGCT
TCCGGTTCTGTCTTTTCGCTG
CCGGTTCTGTCTTTTCGCTGG

Explicação

A opção -a faz com que perl aja como awk , dividindo suas linhas de entrada no valor dado por -F e salvando-as em @F . Como -F aqui está vazio, o resultado é que os elementos da matriz @F são os caracteres da linha. A opção -l ativa chomp automaticamente e também adiciona \n a cada chamada print .

O script em si simplesmente incrementa um contador ( $i ) de 0 até o comprimento da matriz ( $#F ) e o faz contanto que $i seja menor ou igual ao comprimento da matriz menos 20, para só obtém sequências do tamanho certo. Em seguida, ele imprime a fatia da matriz do valor atual de $i até $i+20 .

Se você executar isso com -MO=Deparse para analisar o que está fazendo, será possível ver se ele é executado:

$ perl -MO=Deparse -F'' -lane 'for($i=0;$i<=$#F-20;$i++){print @F[$i..$i+20]}' file
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our @F = split(//, $_, 0);
    for ($i = 0; $i <= $#F - 20; ++$i) {
        print @F[$i .. $i + 20];
    }
}
-e syntax OK
    
por 06.01.2016 / 10:50
3

Assumindo que entendi corretamente, com awk , isso deve ser

awk -v s=CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG '
  BEGIN{while (length(x=substr(s, ++i, 20)) == 20) {print x} exit}'
CCGGTCTCTTCCGGTTCTGT
CGGTCTCTTCCGGTTCTGTC
GGTCTCTTCCGGTTCTGTCT
GTCTCTTCCGGTTCTGTCTT
TCTCTTCCGGTTCTGTCTTT
CTCTTCCGGTTCTGTCTTTT
TCTTCCGGTTCTGTCTTTTC
CTTCCGGTTCTGTCTTTTCG
TTCCGGTTCTGTCTTTTCGC
TCCGGTTCTGTCTTTTCGCT
CCGGTTCTGTCTTTTCGCTG
CGGTTCTGTCTTTTCGCTGG
    
por 05.01.2016 / 19:21
3

Uma versão bash -only:

s=CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG
for ((i=0; i < ${#s} - 20; i++))
do 
  echo ${s:i:20}
done

CCGGTCTCTTCCGGTTCTGT
CGGTCTCTTCCGGTTCTGTC
GGTCTCTTCCGGTTCTGTCT
GTCTCTTCCGGTTCTGTCTT
TCTCTTCCGGTTCTGTCTTT
CTCTTCCGGTTCTGTCTTTT
TCTTCCGGTTCTGTCTTTTC
CTTCCGGTTCTGTCTTTTCG
TTCCGGTTCTGTCTTTTCGC
TCCGGTTCTGTCTTTTCGCT
CCGGTTCTGTCTTTTCGCTG

O loop leva um i ndex de zero até "comprimento de s" menos 20 e imprime 20 caracteres de "s" começando nesse índice.

Estritamente em uma linha:

s=CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG; for ((i=0; i < ${#s} - 20; i++)); do echo ${s:i:20}; done
    
por 05.01.2016 / 20:54
2
sed -n '
  /.\{21,\}/ {
    h
    s/.//
    H
    x
  }
  s/\(.\{,20\}\).*\n/\n/
  P
  D
' <<< "CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG"
CCGGTCTCTTCCGGTTCTGT
CGGTCTCTTCCGGTTCTGTC
GGTCTCTTCCGGTTCTGTCT
GTCTCTTCCGGTTCTGTCTT
TCTCTTCCGGTTCTGTCTTT
CTCTTCCGGTTCTGTCTTTT
TCTTCCGGTTCTGTCTTTTC
CTTCCGGTTCTGTCTTTTCG
TTCCGGTTCTGTCTTTTCGC
TCCGGTTCTGTCTTTTCGCT
CCGGTTCTGTCTTTTCGCTG
CGGTTCTGTCTTTTCGCTGG

Uma versão de 'uma linha' pode ser

sed -n -e '/.\{21,\}/ {h;s/.//;H;x}' -e 's/\(.\{,20\}\).*\n/\n/' -e 'P;D' <<< "CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG"

ou (ligeiramente mais legível, com sintaxe estendida)

sed -nE -e '/.{21,}/ {h;s/.//;H;x}' -e 's/(.{,20}).*\n/\n/' -e 'P;D' <<< "CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG"

ou se você não é religioso em fazer tudo com sed

sed -nE \
  -e '/.{21,}/ {h;s/.//;H;x}' -e 'P;D' <<< "CCGGTCTCTTCCGGTTCTGTCTTTTCGCTGG" \
| cut -c-20
    
por 05.01.2016 / 21:38
1
sed -ne:20 -e's/./&\n/20;/\n/{P;s///;s/.//;}' -et20

Isso funciona com sed , se eu obtiver a pergunta, ou seja,

CCGGTCTCTTCCGGTTCTGT
CGGTCTCTTCCGGTTCTGTC
GGTCTCTTCCGGTTCTGTCT
GTCTCTTCCGGTTCTGTCTT
TCTCTTCCGGTTCTGTCTTT
CTCTTCCGGTTCTGTCTTTT
TCTTCCGGTTCTGTCTTTTC
CTTCCGGTTCTGTCTTTTCG
TTCCGGTTCTGTCTTTTCGC
TCCGGTTCTGTCTTTTCGCT
CCGGTTCTGTCTTTTCGCTG
CGGTTCTGTCTTTTCGCTGG

Parece o mesmo que todos os outros, no entanto. É muito fácil com sed - contanto que haja pelo menos 20 caracteres em seu espaço de padrão, ele anexará uma nova linha ao 20, imprimirá até a nova linha e removerá a nova linha e o primeiro caractere antes de retornar ao espaço padrão novamente.

Com alguns sed , talvez seja necessário usar uma nova linha literal no lugar de n após a referência de substituição & - e, honestamente, essa é a melhor maneira de fazer isso, mas é mais difícil mostrar isso tipo de coisa em uma página da web.

    
por 06.01.2016 / 15:25