Eu apresento aqui quatro soluções, duas usando sed
, uma usando awk
e uma usando perl
. Para começar:
$ sed -r 's/^(>[^ ]+) .*//' inputfile
Em sua entrada de amostra, isso produz a saída:
>YAL001C
LTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*
O código usa o comando substituto do sed s
. O comando substituto está no formato s/old/new/
. Nesse caso, a parte "antiga" consiste nessas partes:
-
^
Isto é sed-speak para o início de uma linha.
-
(>[^ ]+)
Refere-se a um grupo de caracteres que consiste em um colchete angular seguido por um ou mais caracteres não-brancos. Como isso está entre parênteses, poderemos nos referir a ele mais tarde como
.
-
.*
Isso se refere a um espaço em branco seguido por qualquer número de qualquer caractere.
Quando o comando substituto for concluído, toda a linha será substituída apenas pelos caracteres >
e não em branco que a seguem imediatamente.
Qualquer linha que não comece com essa combinação será enviada para a saída inalterada.
Solução alternativa
Nos comentários, a steeldriver sugere uma abordagem alternativa:
sed '/^>/ s/\s.*//'
Nesta solução, o comando substituto é precedido pelo modificador /^>/
, que restringe o comando substituto a operar apenas nas linhas que começam com >
. Sabendo que a linha começa com um colchete angular, então só é necessário remover o primeiro espaço em branco e tudo o que segue o primeiro espaço em branco. Isto é o que o comando s/\s.*//
faz.
Todas as outras linhas são transmitidas inalteradas.
Solução alternativa usando awk
awk '/^>/ {print $1;next} 1' inputfile
Este script awk
consiste em duas expressões:
-
/^>/ {print $1;next}
awk
suporta o mesmo estilo de modificadores quesed
. A expressão inicial, portanto, restringe esse comando para operar apenas nas linhas que começam com>
. Para essas linhas, o primeiro campo é impresso.next
informaawk
para pular para a próxima linha e começar de novo. -
1
1
éawk
de mãozinha enigmática para imprimir a linha inteira. Isso é executado apenas nas linhas para as quais o comandonext
na expressão anterior não é executado, o que significa queawk
atinge este comando somente se a linha não iniciar com>
.
Solução alternativa usando perl
a steeldriver também sugere:
perl -anle 'print $F[0] if /^>/ || $_'
As quatro opções têm o seguinte significado:
-
-n
diz aperl
para fazer um loop implicitamente nas linhas de entrada -
-a
diz ao perl para ativar o preenchimento automático, criando o@F
array -
-l
ativa o processamento automático de finalização de linha -
-e
diz para executar o comando que segue, eliminando a necessidade de um arquivo de script perl.
O comando perl é bastante legível:
print $F[0] if /^>/ || $_
Este comando imprime o primeiro campo se a linha começar com >
. Caso contrário, imprime toda a linha.