Como posso adicionar uma linha de quebra após o cabeçalho de uma sequência e antes da sequência real?

6

Eu tenho um arquivo com múltiplas sequências, o problema é que depois do id existe um espaço e então a sequência atual, eu quero adicionar uma linha de quebra entre o id e a sequência atual.

Isso é o que eu tenho:

UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA

Isto é o que eu quero que pareça:

UniRef90_Q8YC41 Putative binding protein BMEII0691
MNRFIAFFRSVFLIGLVATAFGRACA

Se for possível, prefiro que pareça com isso

UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
    
por asp2_downhill 19.08.2016 / 23:41

3 respostas

10
  • Usando awk , imprimindo o primeiro e o último campo com \n como delimitador:

    awk '{printf "%s\n%s\n", , $NF}' file.txt
    
  • Usando sed , capturando o primeiro e o último campo ao corresponder e usar em substituição:

    sed -E 's/([^[:blank:]]+).*[[:blank:]]([^[:blank:]]+)$/\n/' file.txt
    
  • Com perl , lógica semelhante a sed :

    perl -pe 's/^([^\s]+).*\s([^\s]+)/\n/' file.txt
    
  • Usando bash , abordagem mais lenta , criando uma matriz de cada linha e imprimindo o primeiro e último elemento da matriz, separando-os por \n :

    while read -ra line; do printf '%s\n%s\n' "${line[0]}" \
           "${line[$((${#line[@]]}-1))]}"; done <file.txt
    
  • Com python , criando uma lista contendo elementos separados por espaços em branco de cada linha e, em seguida, imprimindo o primeiro e o último elemento da lista, separando por \n :

    #!/usr/bin/env python3
    with open("file.txt") as f:
        for line in f:
            line = line.split()
            print(line[0]+'\n'+line[-1])
    

Exemplo:

$ cat file.txt                               
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA

$ awk '{printf "%s\n%s\n", , $NF}' file.txt                             
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

$ sed -E 's/([^[:blank:]]+).*[[:blank:]]([^[:blank:]]+)$/\n/' file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

$ perl -pe 's/^([^\s]+).*\s([^\s]+)/\n/' file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA


$ while read -ra line; do printf '%s\n%s\n' "${line[0]}" "${line[$((${#line[@]]}-1))]}"; done <file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

>>> with open("file.txt") as f:
...     for line in f:
...         line = line.split()
...         print(line[0]+'\n'+line[-1])
... 
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
    
por heemayl 19.08.2016 / 23:51
6

Versão Ruby

File.open(ARGV[0]) do |f|
  f.each do |line|
    puts "#{line.partition(' ')[0] + "\n" + line.rpartition(' ')[-1]}"
  end
end

Salve como qualquer nome, digamos line_breaker.rb e execute-o com ruby line_breaker.rb file.txt , enquanto arquivo.txt é o arquivo onde você tem as sequências armazenadas.

    
por Anwar 20.08.2016 / 01:52
6

Nesta resposta:

  1. bash + xargs one-liner
  2. python one-liner
  3. Ruby one-liner

1. bash + xargs versão.

$> cat input_file.txt  | xargs -L 1 bash -c 'for i; do : ; done ; echo ;echo $i' bash 

Isso essencialmente dá a cada linha o bash como argumentos de linha de comando, loop até chegarmos ao último, e ecoá-los.

Demo:

$> cat input_file.txt                                                                     
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
$> cat input_file.txt  | xargs -L 1 bash -c 'for i; do : ; done ; echo ;echo $i' bash   
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

Versão ainda mais curta:

$> cat input_file.txt  | xargs -L 1 bash -c 'echo ;echo ${@: -1}' bash                  
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

2. python one-liner

Este one-liner monta uma lista de strings que são basicamente first word + newline + last word. Finalmente, ele imprime todos os itens da lista como uma string unida à nova linha.

python -c 'import sys ; print "\n".join([ l.split()[0] + "\n" + l.split()[-1]  for l in sys.stdin ])' < input_file.txt

Demonstração de uso:

$ python -c 'import sys ; print "\n".join([ l.split()[0] + "\n" + l.split()[-1]  for l in sys.stdin ])' < input_file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

3. Ruby um forro

Neste forro, -n flag funciona como while gets . . . end loop. $_ detém o valor de cada linha lida, então por cada linha nós dividimos em uma matriz de palavras, e depois imprimimos primeiro e último.

$ ruby -ne 'words=$_.split(); puts words[0],words[-1]' < input_file.txt                   
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
    
por Sergiy Kolodyazhnyy 20.08.2016 / 00:24