
У меня есть файл, показанный ниже:
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
Я хочу напечатать определенное число нуклеотидов в диапазоне, как в файле (последовательность считывается из другого файла "sequence.fasta"). Например, для файла sequence.fasta как:
>gi1234 HIVgenome|NC_909999.1
AACTGCGTGTGTGTCCACACAACACTGGGGGACACACAACAACAACACTGGGGGACACACTGGGACAACACTGGGGGACAGGACACTGTACAACACTGGGTGTGTCGGGACAGTACACATGTTGGGGGGGTGTGTCGGACAACACTGGGGGACATGTGTGTACAACACTGGGGGACAGTGACGACGACAACACTGGGGGACACGAGCGTTGTGAGCAGGTGACAACACTGGGGGACAGTGTTTTTACAACACTGGGGGACATTTTTGAGCAGCGACGCAGCGTTGTGGGGTGTGTCGGAAGGTGTGTCGTGTGTCGTGTGTC
Outputp должен быть
36 - 56 ACAACAACAACACTGGGGGAC
37 - 67 CAACAACAACACTGGGGGACAACACTGGGAC
& скоро...
до
843 - 863 GTGT....
Какой самый простой способ сделать это с помощью скриптов оболочки?
решение1
Этот вопрос требует больших усилий по программированию, чем может предложить этот форум (я зарабатываю на жизнь этим видом программирования).
TheФормат файла DDBJ/ENA/GenBank(первый файл в вопросе) является сложным и позволяет CDS (кодирующим частям геномной последовательности) быть не просто простыми или соединенными, но и дополненными и их комбинациями. Более того, позиционные координаты могут иметьмодификаторыкоторые необходимо будет учесть для универсального решения.
Лучше всего обратиться к местному биоинформатику (или программисту) или на форум по биоинформатике, например, StackExchange.Сайт биоинформатики. Они укажут вам на существующие инструменты для решения подобных задач или, зная биоинформатиков, дадут вам какой-нибудь необычный скрипт BioPerl/BioPython, который, скорее всего, сработает чаще, чем нет ;-)
Одинвозможныймаршрут будет использоватьИзвлекатель признаков GenBank, но его использование в режиме онлайн, скорее всего, не будет лучшим вариантом для чего-либо, кроме небольших наборов данных.
решение2
Хотя я и дал свой предыдущий ответ, я рассмотрел подзадачу извлечения определенной подпоследовательности из файла fasta. Решение состоит из двух частей:
- Скрипт
sh
оболочки, который выполняет анализ командной строки и вызывает... - Скрипт
awk
, который выполняет анализ файла fasta.
Я решил разместить это здесь, потому что это показывает
- Как выполнить синтаксический анализ параметров командной строки в скрипте оболочки.
- Что можно написать
awk
сценарий, а не простоawk
«однострочные» сообщения.
Предположения:
- Идентификатор последовательности будет располагаться сразу после
>
в строке заголовка, за которым следует символ пробела. - В данных последовательности нет пробелов.
Сценарий называется extract.sh
.
Для запуска, получения последовательности для идентификатора последовательности gi1234
между позициями 36 и 183 (включительно):
$ sh extract.sh -i gi1234 -a 36 -b 183 <sequence.fa
ACAACAACAACACTGGGGGACACACTGGGACAACACTGGGGGACA
GGACACTGTACAACACTGGGTGTGTCGGGACAGTACACATGTTGGGGGGGTGTGTCGGACAACACTGGGGGACATGTGTG
TACAACACTGGGGGACAGTGACG
Вывод неформатирован. В этом случае я взял данные в вопросе и вставил переносы строк после каждого 80-го символа перед запуском скрипта.
Скрипт оболочки ( 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
Сценарий awk
( 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;
}
решение3
Я решал похожую проблему, но столкнулся с некоторыми трудностями при попытке использовать скрипты, предоставленные в одном из ответов (оба — WSL и Mac)...
Поэтому я продолжил поиски и нашел довольно простое решение: это getfasta
функция из bedtools
пакета!
https://bedtools.readthedocs.io/en/latest/content/tools/getfasta.html