Faça strings mais longas de substrings mantendo uma nova linha entre cada string

4

Eu tenho um arquivo que contém strings como:

GTACGACGGAGTGTTATAAGATGGGAAATCGGATACCAGATGAAATTGTGGATCGGTGCAAAA
GTCGGCAGATATCGTTGAAGTCATAGGTGATTATGTTCAATTAAAGAAGCAAGGCCGAAACTAC
TTTGGACTCTGTCCTTTTCATGGAGAAAGCACACCTTCGTTTTCCGTATCGCCCGACAAACAGAT
TTTTCATTGCTTTGGCTGCGGAGCGGGCGGCAATGTTTTCTCTTTTTTAAGGCAGATGGAAGGCT
ATTCTTTTGCCGAGTCGGTTTCTCACCTTGCTGACAAATACCAAATTGATTTTCCAGATGATATAA
CAGTCCATTCCGGAGCCCGGCCAGAG      

TCTTCTGGAGAACAAAAAATGGCTGAGGCACATGAGCTCCTGAAGAAATTTTACCATCATTTGT
TAATAAATACAAAAGAAGGTCAAGAGGCACTGGATTATCTGCTTTCTAGGGGCTTTACGAAAGA
GCTGATTAATGAATTTCAGATTGGCTATGCTCTTGATTCTTGGGACTTTATCACGAAA

CCGCTGTATTCTCAGCCAAGCGGTATAGTCTCCGCTGTATTCTCAGCCCCAGCCGTTCCACTCAG
AGGAACTTTAAAGGATGTTCCTGTTGAGGGCTCATCATCGTCATCGTCATCATCATCATCATCAT
CATCATCATCATCATCAACATCAACCGTCGCACCAGCAAATAAGGCAAGAACTGGAGAAGACGC
AGAAGGCAGTCAAGATTCTAGTGGTACTGAAGCTTCTGGTAGCCAGGGTTCTGAAGAGGAAGG
TAGTGAAGACGATGGCCAAACTAGTGCTGCTTCCCAACCCACTACTCCAGCTCAAAGTGAAGGC
GCAACTACCGAAACCATAGAAGCTACTCCAAAAGAAGAATGCGGCACTTCATTTGTAATGTGGT

que eu quero colocar como três longas cordas separadas apenas por uma linha vazia, ou seja, assim:

  GTACGACGGAGTGTTATAAGATGGGAAATCGGATACCAGATGAAATTGTGGATCGGTGCAAAAGTCGGCAGATATCGTTGAAGTCATAGGTGATTATGTTCAATTAAAGAAGCAAGGCCGAAACTACTTTGGACTCTGTCCTTTTCATGGAGAAAGCACACCTTCGTTTTCCGTATCGCCCGACAAACAGATTTTTCATTGCTTTGGCTGCGGAGCGGGCGGCAATGTTTTCTCTTTTTTAAGGCAGATGGAAGGCTATTCTTTTGCCGAGTCGGTTTCTCACCTTGCTGACAAATACCAAATTGATTTTCCAGATGATATAACAGTCCATTCCGGAGCCCGGCCAGAG

  TCTTCTGGAGAACAAAAAATGGCTGAGGCACATGAGCTCCTGAAGAAATTTTACCATCATTTGTTAATAAATACAAAAGAAGGTCAAGAGGCACTGGATTATCTGCTTTCTAGGGGCTTTACGAAAGAGCTGATTAATGAATTTCAGATTGGCTATGCTCTTGATTCTTGGGACTTTATCACGAAA

  CCGCTGTATTCTCAGCCAAGCGGTATAGTCTCCGCTGTATTCTCAGCCCCAGCCGTTCCACTCAGAGGAACTTTAAAGGATGTTCCTGTTGAGGGCTCATCATCGTCATCGTCATCATCATCATCATCATCATCATCATCATCATCAACATCAACCGTCGCACCAGCAAATAAGGCAAGAACTGGAGAAGACGCAGAAGGCAGTCAAGATTCTAGTGGTACTGAAGCTTCTGGTAGCCAGGGTTCTGAAGAGGAAGGTAGTGAAGACGATGGCCAAACTAGTGCTGCTTCCCAACCCACTACTCCAGCTCAAAGTGAAGGCGCAACTACCGAAACCATAGAAGCTACTCCAAAAGAAGAATGCGGCACTTCATTTGTAATGTGGT

Como corrigir isso no Unix. Eu tentei com o awk e o sed mas não consegui alcançar o resultado que quero.

    
por Faiz Lotfy 10.10.2015 / 01:03

6 respostas

3
$ awk '/./{printf "%s",$0;next} {print "\n";} END{if (/./)print""}' file
GTACGACGGAGTGTTATAAGATGGGAAATCGGATACCAGATGAAATTGTGGATCGGTGCAAAAGTCGGCAGATATCGTTGAAGTCATAGGTGATTATGTTCAATTAAAGAAGCAAGGCCGAAACTACTTTGGACTCTGTCCTTTTCATGGAGAAAGCACACCTTCGTTTTCCGTATCGCCCGACAAACAGATTTTTCATTGCTTTGGCTGCGGAGCGGGCGGCAATGTTTTCTCTTTTTTAAGGCAGATGGAAGGCTATTCTTTTGCCGAGTCGGTTTCTCACCTTGCTGACAAATACCAAATTGATTTTCCAGATGATATAACAGTCCATTCCGGAGCCCGGCCAGAG      

TCTTCTGGAGAACAAAAAATGGCTGAGGCACATGAGCTCCTGAAGAAATTTTACCATCATTTGTTAATAAATACAAAAGAAGGTCAAGAGGCACTGGATTATCTGCTTTCTAGGGGCTTTACGAAAGAGCTGATTAATGAATTTCAGATTGGCTATGCTCTTGATTCTTGGGACTTTATCACGAAA

CCGCTGTATTCTCAGCCAAGCGGTATAGTCTCCGCTGTATTCTCAGCCCCAGCCGTTCCACTCAGAGGAACTTTAAAGGATGTTCCTGTTGAGGGCTCATCATCGTCATCGTCATCATCATCATCATCATCATCATCATCATCATCAACATCAACCGTCGCACCAGCAAATAAGGCAAGAACTGGAGAAGACGCAGAAGGCAGTCAAGATTCTAGTGGTACTGAAGCTTCTGGTAGCCAGGGTTCTGAAGAGGAAGGTAGTGAAGACGATGGCCAAACTAGTGCTGCTTCCCAACCCACTACTCCAGCTCAAAGTGAAGGCGCAACTACCGAAACCATAGAAGCTACTCCAAAAGAAGAATGCGGCACTTCATTTGTAATGTGGT

Observe que a saída esperada tem cinco linhas, duas das quais estão vazias:

$ awk '/./{printf "%s",$0;next} {print "\n";} END{if (/./)print""}' file | wc -l
5

Como funciona

  • /./{printf "%s",$0;next}

    Se a linha atual tiver pelo menos um caractere, imprima sem uma nova linha. Então, pule o resto dos comandos e pule para a linha next .

  • print "\n";

    Se chegamos aqui, estamos em uma linha vazia. Imprima dois caracteres de nova linha.

  • END{if (/./)print""}

    Depois que chegarmos ao final do arquivo, verifique se a última linha estava vazia ou não. Se não estiver vazio, imprimiremos um caractere final de nova linha.

por 10.10.2015 / 01:24
4
sed -e:t -e'N;/\n$/!s/\n//;$!tt' <in >out

Isso anexa a linha N ext ao espaço padrão seguindo um caractere \n ewline inserido para cada iteração. Se um caractere de \n ewline for ! depois, o caractere $ last no espaço de padrão - como seria se a linha apenas anexada estivesse em branco - o caractere de nova linha inserido será s/// ubstituted away. Para cada linha de entrada que é ! não a $ anterior, então t est para uma substituição bem-sucedida e, se necessário, ramificar-se de volta para o teste : label para extrair novamente a linha N ext .

E os resultados são:

GTACGACGGAGTGTTATAAGATGGGAAATCGGATACCAGATGAAATTGTGGATCGGTGCAAAAGTCGGCAGATATCGTTGAAGTCATAGGTGATTATGTTCAATTAAAGAAGCAAGGCCGAAACTACTTTGGACTCTGTCCTTTTCATGGAGAAAGCACACCTTCGTTTTCCGTATCGCCCGACAAACAGATTTTTCATTGCTTTGGCTGCGGAGCGGGCGGCAATGTTTTCTCTTTTTTAAGGCAGATGGAAGGCTATTCTTTTGCCGAGTCGGTTTCTCACCTTGCTGACAAATACCAAATTGATTTTCCAGATGATATAACAGTCCATTCCGGAGCCCGGCCAGAG

TCTTCTGGAGAACAAAAAATGGCTGAGGCACATGAGCTCCTGAAGAAATTTTACCATCATTTGTTAATAAATACAAAAGAAGGTCAAGAGGCACTGGATTATCTGCTTTCTAGGGGCTTTACGAAAGAGCTGATTAATGAATTTCAGATTGGCTATGCTCTTGATTCTTGGGACTTTATCACGAAA

CCGCTGTATTCTCAGCCAAGCGGTATAGTCTCCGCTGTATTCTCAGCCCCAGCCGTTCCACTCAGAGGAACTTTAAAGGATGTTCCTGTTGAGGGCTCATCATCGTCATCGTCATCATCATCATCATCATCATCATCATCATCATCAACATCAACCGTCGCACCAGCAAATAAGGCAAGAACTGGAGAAGACGCAGAAGGCAGTCAAGATTCTAGTGGTACTGAAGCTTCTGGTAGCCAGGGTTCTGAAGAGGAAGGTAGTGAAGACGATGGCCAAACTAGTGCTGCTTCCCAACCCACTACTCCAGCTCAAAGTGAAGGCGCAACTACCGAAACCATAGAAGCTACTCCAAAAGAAGAATGCGGCACTTCATTTGTAATGTGGT
    
por 10.10.2015 / 02:20
3

O modo slurping de parágrafo do Perl pode ser usado para isso.

perl -n -00 -e 's/\n//g; print $_,"\n";' gene.txt

A opção -00 diz ao perl para ler a entrada um parágrafo por vez, em vez de uma linha por vez. Um "parágrafo" é definido como um bloco de texto separado por uma linha em branco.

O resto do script apenas retira feeds de linha de cada linha dos parágrafos e imprime cada um deles como uma longa string com um avanço de linha no final.

Se você quiser que a saída também esteja em "parágrafos", adicione um extra "\ n":

 perl -n -00 -e 's/\n//g; print $_,"\n\n";' gene.txt
    
por 10.10.2015 / 01:30
2

Outra solução usando o modo de parágrafo de awk

awk -v RS= -vORS='\n\n' '{gsub(/\n/, ""); print}' file
    
por 10.10.2015 / 02:25
1
perl -p -e 's/\n$//; s/^$/\n\n/;'

Lê de stdin ou arquivos nomeados, escreve para stdout. Um uso prático seria:

perl -p -e 's/\n$//; s/^$/\n\n/;' file1 file2 file3 >outfile

Se não houver uma linha em branco após o último parágrafo, isso deixará de gerar uma nova linha no EOF. Manipulação isso é bastante fácil; apenas faça echo >>outfile depois.

    
por 10.10.2015 / 01:07
1
tr "\n" _ <gene.txt | sed -E "s/__/=/g" | tr -d _ | tr = "\n"

Uma solução com comandos simples:

  1. Substitua \n por _ . Agora é uma linha única e sed pode processá-la.
  2. Substitua __ por = : estas foram as duas novas linhas consecutivas (as linhas vazias) na origem
  3. Remover _ restante
  4. Substitua = por \n
por 10.10.2015 / 08:50

Tags