
Tenho um arquivo conforme mostrado abaixo:
CDS join(36..56,37..67)
CDS 36..183
CDS 457..565
CDS join(505..519,521..596)
CDS join(577..591,725..770)
CDS join(516..591,725..899)
CDS 508..556
CDS 571..841
CDS complement(619..788)
CDS 843..863
Quero imprimir o número específico do intervalo de nucleotídeos como no arquivo (a sequência é lida de outro arquivo "sequence.fasta"). Por exemplo, para o arquivo sequencia.fasta como:
>gi1234 HIVgenome|NC_909999.1
AACTGCGTGTGTGTCCACACAACACTGGGGGACACACAACAACAACACTGGGGGACACACTGGGACAACACTGGGGGACAGGACACTGTACAACACTGGGTGTGTCGGGACAGTACACATGTTGGGGGGGTGTGTCGGACAACACTGGGGGACATGTGTGTACAACACTGGGGGACAGTGACGACGACAACACTGGGGGACACGAGCGTTGTGAGCAGGTGACAACACTGGGGGACAGTGTTTTTACAACACTGGGGGACATTTTTGAGCAGCGACGCAGCGTTGTGGGGTGTGTCGGAAGGTGTGTCGTGTGTCGTGTGTC
A saídap deve ser
36 - 56 ACAACAACAACACTGGGGGAC
37 - 67 CAACAACAACACTGGGGGACAACACTGGGAC
& breve...
até
843 - 863 GTGT....
Qual seria a maneira mais fácil de fazer isso por meio de scripts de shell?
Responder1
Esta questão requer um esforço de programação maior do que pode ser oferecido por este fórum (eu faço esse tipo de programação para viver).
OFormato de arquivo DDBJ/ENA/GenBank(o primeiro arquivo da questão) é complexo e permite que os CDSs (as partes codificantes de uma sequência genômica) sejam não apenas simples ou unidos, mas complementados e suas combinações. Além disso, as coordenadas posicionais podem termodificadoresque, para uma solução genérica, precisaria ser tratado.
Seria melhor perguntar a um bioinformático local (ou programador) ou em um fórum de bioinformática, como o StackExchangeSite de bioinformática. Eles indicarão ferramentas existentes para fazer esse tipo de coisa ou, conhecendo os bioinformáticos, fornecerão algum script BioPerl/BioPython peculiar que provavelmente funcionará com mais frequência ;-)
Umpossívelcaminho seria usar oExtrator de recursos GenBank, mas usá-lo on-line provavelmente não será a melhor opção para nada além de pequenos conjuntos de dados.
Responder2
Embora eu tenha dado minha resposta anterior, examinei o subproblema de extrair uma subsequência específica de um arquivo fasta. A solução está em duas partes:
- Um
sh
script de shell que analisa a linha de comando e chama ... - Um
awk
script que faz a análise do arquivo fasta.
Resolvi postar isso aqui porque mostra
- Como fazer a análise de opções de linha de comando em um script de shell.
- Que é possível escrever um
awk
roteiro, em vez de apenasawk
“one-liners”.
Premissas:
- O ID de sequência ocorrerá diretamente após na
>
linha do cabeçalho, seguido por um caractere de espaço. - Não há espaços em nenhum lugar nos dados da sequência.
O script é chamado extract.sh
.
Para executar, obtendo a sequência para ID de sequência gi1234
entre as posições 36 e 183 (inclusive):
$ sh extract.sh -i gi1234 -a 36 -b 183 <sequence.fa
ACAACAACAACACTGGGGGACACACTGGGACAACACTGGGGGACA
GGACACTGTACAACACTGGGTGTGTCGGGACAGTACACATGTTGGGGGGGTGTGTCGGACAACACTGGGGGACATGTGTG
TACAACACTGGGGGACAGTGACG
A saída não está formatada. Nesse caso, peguei os dados da pergunta e inseri quebras de linha a cada 80 caracteres antes de executar o script.
O script de shell ( extract.sh
):
#!/bin/sh
usage() {
cat <<USAGE_END
Usage:
sh $0 -i seq_id -a start -b end <sequence.fa
USAGE_END
}
while getopts "a:b:i:" opt; do
case $opt in
a) start_pos="$OPTARG" ;;
b) end_pos="$OPTARG" ;;
i) seq_id="$OPTARG" ;;
*) usage; exit 1 ;;
esac
done
if [ "x$seq_id" = "x" ]; then
echo "Missing sequence ID (-i seq_id)"
usage
exit 1
fi
if [ "x$start_pos" = "x" -o "x$end_pos" = "x" ]; then
echo "Missing either start or end coordinates (-a, -b)"
usage
exit 1
fi
if [ ! -f "extract.awk" ]; then
echo "Can not find the extract.awk AWK script!"
exit 1
fi
awk -v id="$seq_id" -v a="$start_pos" -v b="$end_pos" -f extract.awk
O awk
roteiro ( extract.awk
):
# state == 0: not yet at wanted sequence entry in file
# state == 1: found sequence entry, not yet at start position
# state == 2: found start position, not yet at end position
# off: offset in sequence read so far
BEGIN { state = 0 }
state == 0 && $0 ~ "^>" id " " {
# We found the sequence entry we're looking for.
state = 1;
off = 0;
next;
}
state > 0 && /^>/ {
# New sequence header found while parsing sequence, terminate.
exit;
}
state == 1 {
len = length($0);
if (len + off < a) {
# Start position is not on this line.
off += len;
next;
}
state = 2;
if (len + off >= b) {
# Whole sequence is found on this line.
print(substr($0, a - off, b - a + 1))
exit;
}
# Output partial start of sequence.
print(substr($0, a - off , len - (a - off) + 1))
off += len;
next;
}
state == 2 {
len = length($0);
if (off > b) {
# (we should not arrive here)
exit;
}
if (len + off < b) {
# End position is not on this line.
print($0);
off += len;
next;
}
# We found the end position, output line until end position
# and terminate.
print(substr($0, 1, b - off));
exit;
}
Responder3
Eu estava resolvendo um problema semelhante, mas costumava ter alguns problemas ao tentar usar os scripts fornecidos em uma das respostas (ambos WSL, Mac) ...
Continuei pesquisando e encontrei uma solução bem fácil: é a getfasta
função da bedtools
suíte!
https://bedtools.readthedocs.io/en/latest/content/tools/getfasta.html