Как использовать строки в файле в качестве ключевого слова для grep?

#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 для каждого отдельного штрих-кода в каждом отдельном образце. Я знаю, что это неверно, потому что, когда я пишу 1 grep команду для каждого штрих-кода, как в моем исходном вопросе, где 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 цикл, а затем возвращается к чтению следующей строки из файла и т.д.