如何使用文件中的行作为grep的关键字?

时间:2019-03-05 21:58:15

标签: bash grep cat

我在这里和其他站点上搜索了很多问题,人们提出了一些可以解决我问题的建议,但是我认为我的代码存在一些我不认识的问题。

我从NGS测序中提取了24个.fasta文件,它们的长度均为150bp。每个文件大约有100万次读取。这些读数来自靶向测序,其中我们用感兴趣的基因的cDNA和独特的条形码序列电镀了载体。我需要查看测序文件中是否存在与特定基因相对应的条形码序列。

我有一个条形码序列的.txt列表,我希望将其传递给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目录中返回空的新文件。我还尝试了一个嵌套循环,在该循环中,我尝试使条形码序列成为一个像$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    

我想要一个具有以下内容的.txt输出文件:

<barcode sequence>: <# of times that bc was found> 
对于每个.fasta文件

,因为我想将所有样本放在一起以制作一张大的excel表,该表显示每个条形码以及在每个样本中发现了多少次。

请帮忙,我已经尽力了。

编辑

这是BarcodeScreenSeq.txt文件的外观。这只是一个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

2 个答案:

答案 0 :(得分:1)

Windows行尾

您的BarcodeScreenSeq.txt具有Windows行尾。每行以特殊字符\r\n结尾。诸如grep之类的Linux工具仅处理linux行尾\r并解释您的文件...

TATTATG\r\n
ATGAAAG\r\n
...

查找模式TATTATG\rATGAAAG\r,...(请注意末尾的\r)。由于\r没有匹配项。

任何一个:通过运行dos2unix BarcodeScreenSeq.txtsed -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 :(得分:0)

您可以一次读取一行文本文件,然后使用重定向分别处理每一行,如下所示:

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