#bash #grep #cat
#bash #grep #cat
Вопрос:
Я искал множество вопросов здесь и на других сайтах, и люди предлагали то, что должно решить мою проблему, но я думаю, что с моим кодом что-то не так, что я просто не распознаю.
У меня есть 24 файла .fasta из NGS sequencing длиной 150 бит. Для каждого файла требуется примерно 1 МЛН операций чтения. Считанные данные получены в результате целевого секвенирования, в ходе которого мы гальванически обработали векторы кДНК для интересующих генов и уникальной последовательностью штрих-кода. Мне нужно просмотреть файлы секвенирования на наличие или отсутствие последовательности штрих-кода, которая соответствует определенному гену.
У меня есть текстовый список последовательностей штрих-кодов, которые я хочу передать grep для поиска штрих-кода в файле .fasta. Я перепробовал так много вариантов этой команды. Я могу предоставить grep каждый штрих-код по отдельности, но это отнимает много времени, я знаю, что можно предоставить ему список последовательностей штрих-кодов и выполнить поиск в каждом .fasta для каждого из штрих-кодов и записать, сколько раз каждый штрих-код встречается в каждом файле.
Вот мой код, в котором я даю ему каждый штрих-код по отдельности:
# Barcode 33
mkdir --mode 755 $dir/BC33
FILES="*.fasta"
for f in $FILES; do
cat "$f" | tr -d "n" | tr ">" "n" | grep 'TATTAGAGTTTGAGAATAAGTAGT' > $dir/BC33/"$f"
done
Я попытался адаптировать его, чтобы мне не приходилось вводить каждую последовательность штрих-кодов по отдельности:
dir="/home/lozzib/AG_Barcode_Seq/"
cd $dir
FILES="*.fasta"
for f in $FILES; do
cat "$f" | tr -d "n" | tr ">" "n" | grep -c -f BarcodeScreenSeq.txt | sort > $dir/Results/"$f"
echo "Finished $f"
done
Но он не ищет последовательности штрих-кодов. С помощью этой итерации он просто возвращает новые файлы в /Results
каталог, которые пусты. Я также попробовал цикл nest, где я попытался сделать последовательность штрих-кодов переменной, которая изменялась подобно $FILES
, но это просто дало мне новый файл с именами моих файлов .fasta:
dir="/home/lozzib/AG_Barcode_Seq/"
cd $dir
FILES="*.fasta"
for f in $FILES; do
for b in `cat /home/lozzib/AG_Barcode_Seq/BarcodeScreenSeq.txt`; do
cat "$f" | grep -c "$b" | sort > $dir/"$f"_Barcode
done ;
done
Мне нужен выходной текстовый файл, содержащий:
<barcode sequence>: <# of times that bc was found>
для каждого файла .fasta, потому что я хочу собрать все образцы вместе, чтобы получился один большой лист Excel, на котором показан каждый штрих-код и сколько раз он был найден в каждом образце.
Пожалуйста, помогите, я перепробовал все, что смог придумать.
Редактировать
Вот что такое BarcodeScreenSeq.txt файл будет выглядеть следующим образом. Это просто текстовый файл, где каждая строка представляет собой последовательность штрих-кодов:
head BarcodeScreenSeq.txt
TATTATGAGAAAGTTGAATAGTAG
ATGAAAGTTAGAGTTTATGATAAG
AATAGATAAGATTGATTGTGTTTG
TGTTAAATGTATGTAGTAATTGAG
ATAGATTTAAGTGAAGAGAGTTAT
GAATGTTTGTAAATGTATAGATAG
AAATTGTGAAAGATTGTTTGTGTA
TGTAAGTGAAATAGTGAGTTATTT
GAATTGTATAAAGTATTAGATGTG
AGTGAGATTATGAGTATTGATTTA
Редактировать
lozzib@gliaserver:~/AG_Barcode_Seq$ file BarcodeScreenSeq.txt
BarcodeScreenSeq.txt: ASCII text, with CRLF line terminators
Комментарии:
1. Вы хотите подсчитать количество строк, в которых отображается последовательность штрих-кодов, или количество раз, когда последовательность штрих-кодов появляется вообще (если штрих-код появляется дважды в одной строке, считается ли это как 1 или 2 появления)?
grep
Поддерживает ли ваш-o
вариант? Разрешено ли вам использовать Perl, или Python, или даже Awk? (Кроме того, что150 bp long
означает? Я не узнаю сокращение для единиц измерения.)2. Кроме того, существует ли какой-либо риск того, что какой-либо из штрих-кодов, которые вы ищете, имеет перекрытия, так что штрих-код 1 заканчивается последовательностью GTA, а штрих-код 2 начинается с последовательности GTA, и если вы найдете штрих-код 1, вы также можете обнаружить, что штрих-код 2 перекрывается с концом штрих-кода 1? Я не уверен, что это вероятная проблема; для вас имело бы значение, если бы такие совпадения были пропущены?
3. Сколько строк в
BarcodeScreenSeq.txt
файле? Сотни, тысячи, миллионы или больше? Все образцы имеют длину 24 символа; все ли они одинаковой длины? Каков диапазон размеров?4. Я хочу знать, сколько раз появляется штрих-код. Оно должно появляться только один раз в строке, но независимо от этого я просто хочу знать, сколько раз оно было найдено. Мне не обязательно использовать grep, я мог бы использовать Perl или Python, но у меня нет никакого опыта написания сценариев такого типа, поэтому я попробовал
grep
сначала. Я не уверен, поддерживает ли он эту-o
опцию.150 bp long
означает, что строки имеют длину 150 пар оснований или символов. Файлы, которые я пытаюсь просмотреть, были.fastq
файлами из секвенсора Illumina, и я преобразовал их в.fasta
файлы, которые можно использоватьgrep
для поиска последовательностей штрих-кодов.5. В файле 150 строк
BarcodeScreenSeq.txt
Ответ №1:
Окончания строк Windows
У вашего BarcodeScreenSeq.txt
есть окончания строк Windows. Каждая строка заканчивается специальными символами rn
. Такие инструменты Linux, как grep
, работают только с окончаниями строк в Linux r
и интерпретируют ваш файл…
TATTATGrn
ATGAAAGrn
...
для поиска шаблонов TATTATGr
, ATGAAAGr
, … (обратите r
внимание на конец). Из-за r
нет совпадения.
Либо: конвертируйте ваш файл сразу после запуска dos2unix BarcodeScreenSeq.txt
или sed -i 's/r//g' BarcodeScreenSeq.txt
. Это изменит ваш файл.
Или: замените все BarcodeScreenSeq.txt
в следующих сценариях на <(tr -d 'r' < BarcodeScreenSeq.txt)
. Это не изменит файл, но увеличит накладные расходы, поскольку файл преобразуется снова и снова.
Команда
grep -c
имеет только один счетчик. Если вы передаете несколько шаблонов поиска одновременно (например, используя -f BarcodeScreenSeq.txt
), вы все равно получаете только одно число для всех шаблонов вместе.
Чтобы подсчитать вхождения каждого шаблона по отдельности, вы можете использовать следующий трюк:
for file in *.fasta; do
grep -oFf BarcodeScreenSeq.txt "$file" |
sort | uniq -c |
awk '{print $2 ": " $1 }' > "Results/$file"
done
grep -o
будет выводить каждое совпадение в виде одной строки.
sort | uniq -c
будет подсчитано, как часто встречается каждая строка.
awk
существует только для изменения формата с #matches pattern
на pattern: #matches
.
Преимущество: команда должна быть довольно быстрой.
Недостаток: шаблоны из BarcodeScreenSeq.txt
, которые не найдены в $file
, вообще не будут перечислены. В вашем результате не будут учитываться строки формы pattern: 0
.
Если вам действительно нужны строки формы pattern: 0
, вы могли бы использовать другой трюк:
for file in *.fasta; do
grep -oFf BarcodeScreenSeq.txt "$file" |
cat - BarcodeScreenSeq.txt |
sort | uniq -c |
awk '{print $2 ": " ($1 - 1) }' > "Results/$file"
done
cat - BarcodeScreenSeq.txt
вставит содержимое BarcodeScreenSeq.txt
в конце grep
выходных данных таким образом, чтобы оно #matches
было на единицу больше, чем должно быть. Число исправлено на awk
.
Комментарии:
1. Если
-o
не поддерживалось, тоgrep
выводилось сообщение об ошибке. Также я никогда не слышал оgrep
реализации, не поддерживающей-o
. Может ли быть, что у вашегоBarcodeScreenSeq.txt
есть окончания строк Windows? Пожалуйста, покажите нам результат выполнения командыfile BarcodeScreenSeq.txt
.2. Итак, второй вариант дает мне файл, как вы сказали, с BarcodeSequence: # of occurrences , но я получаю
0
для каждого отдельного штрих-кода в каждом отдельном образце. Я знаю, что это неверно, потому что, когда я пишу 1grep
команду для каждого штрих-кода, как в моем исходном вопросе, гдеgrep
после него указана последовательность, я нахожу штрих-коды в своих$file
файлах.3. Я добавил выходные данные в качестве редактирования к исходному вопросу
4. @lozzib Спасибо. Не видел этого раньше. Мое предположение было правильным. У вас есть окончания строк в Windows, и вам необходимо преобразовать их в Linux запустите,
dos2unix BarcodeScreenSeq.txt
чтобы преобразовать файл или заменить всеBarcodeScreenSeq.txt
в моем скрипте на<(tr -d 'r' < BarcodeScreenSeq.txt)
5. Я плачу настоящими слезами. Большое вам спасибо! Это сработало! Я бы никогда не узнал о том, что окончания Windows вызывают проблему. Еще раз спасибо! Я действительно ценю это
Ответ №2:
Вы можете читать текстовый файл по одной строке за раз и обрабатывать каждую строку отдельно, используя перенаправление, вот так:
for f in *.fasta; do
while read -r seq; do
grep -c "${seq}" "${f}" > "${dir}"/"${f}"_Barcode
done < /home/lozzib/AG_Barcode_Seq/BarcodeScreenSeq.txt
done
Комментарии:
1. Извините, я все еще не совсем понимаю. Эта строка:
while read -r seq; do
Что такое seq? И почему путь к файлу штрих-кода должен быть в конце?2.
seq
это просто имя переменной, которое я выбрал для представления каждой последовательности, прочитанной из вашего «BarcodeScreenSeq.txt «файл. Вы можете называть это как угодно. Путь к файлу указан в конце, потому что именно так работает перенаправление такого рода:while read -r [line]; do [whatever with 'line']; done < [file]
считывает из файла по одной строке за раз, выполняет с каждой строкой все, что предписываетwhile
цикл, а затем возвращается к чтению следующей строки из файла и т.д.