Como excluir texto entre dois padrões na mesma linha

2

Eu tenho um arquivo com a entrada

sp|O34439|YFLP_BACSU UPF0065 protein YflP OS=Bacillus subtilis (strain 168) GN=yflP PE=3 SV=2
MKKSIILLNILLIFMQGDIRQAAAPRLPDGPIEIVVPAEPSGGWDVTAQAIQSVLRQKQIVKDDVHIVYKSGGGGEK
sp|Q44018|YGB7_CUPNE UPF0065 protein in gbd 5'region OS=Cupriavidus necator PE=3 SV=1
MQRRHFIARAGIAAATAALGLAAMPAQAQADKFPQRPIRLVIGYTAGGSTDIPFRVLADNASKILGQPVIVENK

e precisa obter esta saída:

sp|O34439|YFLP_Bacillus subtilis
MKKSIILLNILLIFMQGDIRQAAAPRLPDGPIEIVVPAEPSGGWDVTAQAIQSVLRQKQIVKDDVHIVYKSGGGGEK
sp|Q44018|YGB7_Cupriavidus necator
MQRRHFIARAGIAAATAALGLAAMPAQAQADKFPQRPIRLVIGYTAGGSTDIPFRVLADNASKILGQPVIVENK

Portanto, preciso excluir tudo entre o padrão >|......|.... e OS=.................... (se puder excluir o OS= e deixar , ainda melhor) e excluir qualquer coisa após o segundo padrão na mesma linha. / p>     

por Leonardo T Rosa 25.08.2017 / 17:12

3 respostas

2

Assumindo muita consistência, você pode usar algo como ...

$ sed -r 's/([^ ]+\|[^ ]+\|[^_]+_)[^_]+ .* OS=([^ ]+ [^ ]+) .*//' file
sp|O34439|YFLP_Bacillus subtilis
MKKSIILLNILLIFMQGDIRQAAAPRLPDGPIEIVVPAEPSGGWDVTAQAIQSVLRQKQIVKDDVHIVYKSGGGGEK
sp|Q44018|YGB7_Cupriavidus necator
MQRRHFIARAGIAAATAALGLAAMPAQAQADKFPQRPIRLVIGYTAGGSTDIPFRVLADNASKILGQPVIVENK

Notas

  • -r use ERE
  • s/old/new replace old com new
  • (some chars) lembre-se de some chars para referência posterior com etc
  • [^ ]+ pelo menos um caractere não espacial ( [^_]+ é pelo menos um caractere não sublinhado)
  • \| literal | desde que em ERE | é usado para alternação
  • .* qualquer número de caracteres
  • referências anteriores a padrões salvos
por Zanna 25.08.2017 / 17:32
3
sed 's/\([^_]*\).*=\([A-Z][a-z ]*\).*/_/' test

faz o que você deseja para o arquivo test e grava a saída no terminal:

> sed 's/\([^_]*\).*=\([A-Z][a-z ]*\).*/_/' test
sp|O34439|YFLP_Bacillus subtilis 
MKKSIILLNILLIFMQGDIRQAAAPRLPDGPIEIVVPAEPSGGWDVTAQAIQSVLRQKQIVKDDVHIVYKSGGGGEK
sp|Q44018|YGB7_Cupriavidus necator 
MQRRHFIARAGIAAATAALGLAAMPAQAQADKFPQRPIRLVIGYTAGGSTDIPFRVLADNASKILGQPVIVENK

Adicione > filename ao final do comando para salvar a saída no arquivo filename .

Explicação

  • \(.*_\) leva tudo até o primeiro sublinhado, salve como grupo 1
  • .*= leva tudo até o primeiro sinal de igual
    • substitua por .*OS= para levar tudo até OS=
  • \([A-Z][a-z ]*\) recebe uma letra maiúscula e todas as letras minúsculas e espaços a seguir, salve-a como grupo 2
    • substitua por \([^ ]*[ ][^ ]*\) para procurar uma string com exatamente um espaço nela
  • .* (espaço anterior não exibido aqui!) ocupe um espaço e o resto da linha
  • grupo 1 seguido pelo grupo 2
por dessert 25.08.2017 / 17:33
1

Isso funcionaria:

$ sed -r 's/(.*_)[A-Z].*=(\w+)\s{1,2}(\w+)\s{1,2}.*\s.*/ /g' file.txt
sp|O34439|YFLP_Bacillus subtilis    
MKKSIILLNILLIFMQGDIRQAAAPRLPDGPIEIVVPAEPSGGWDVTAQAIQSVLRQKQIVKDDVHIVYKSGGGGEK
sp|Q44018|YGB7_Cupriavidus necator
MQRRHFIARAGIAAATAALGLAAMPAQAQADKFPQRPIRLVIGYTAGGSTDIPFRVLADNASKILGQPVIVENK

Explicação:

  • (.*_) - Retorna tudo até a primeira letra maiúscula
  • .*= - Leve até o sinal de igual
  • (\w+)\s{1,2} - Retorna a primeira palavra antes de 1-2 espaços
  • (\w+)\s{1,2} - O mesmo que acima
  • .*\s.* - Pega todo o espaço e depois disso
  • - Retornar grupos capturados
por George Udosen 25.08.2017 / 21:35