简体   繁体   English

来自文件的Grep失败,但文件中的个别行的grep有效

[英]Grep from file fails but grep with individual lines from the file works

I am trying to extract lines from file genome.gff that contain a line from file suspicious.txt. 我正在尝试从文件基因组.gff中提取包含来自文件suspicious.txt的行。 suspicious.txt was derived from genome.gff and every line should match. suspicious.txt来自基因组.gff,每一行都应匹配。

Using grep on a single line from suspicious.txt works as expected: 在suspicious.txt的单行上使用grep可以按预期工作:

grep 'gene10002' genome.gff
NC_007082.3 Gnomon  gene    1269632 1273520 .   +   .   ID=gene10002;Dbxref=BEEBASE:GB54789,GeneID:409846;Name=bur;gbkey=Gene;gene=bur;gene_biotype=protein_coding
NC_007082.3 Gnomon  mRNA    1269632 1273520 .   +   .   ID=rna21310;Parent=gene10002;Dbxref=GeneID:409846,Genbank:XM_393336.5,BEEBASE:GB54789;Name=XM_393336.5;gbkey=mRNA;gene=bur;product=burgundy;transcript_id=XM_393336.5

But every variation on using grep from a file that I've been able to think of or find online produces no output or an empty file: 但是,从我能够想到或在线找到的文件中使用grep的每种变体都不会产生输出或空文件:

grep -f suspicious.txt genome.gff
grep -F -f suspicious.txt genome.gff
while read line; do grep "$line" genome.gff; done<suspicious.txt
while read line; do grep '$line' genome.gff; done<suspicious.txt
while read line; do grep "${line}" genome.gff; done<suspicious.txt
cat suspicious.txt | while read line; do grep '$line' genome.gff; done
cat suspicious.txt | while read line; do grep '$line' genome.gff >> suspicious.gff; done
cat suspicious.txt | while read line; do grep -e "${line}" genome.gff >> suspicious.gff; done
cat "$(cat suspicious_bee_geneIDs_test.txt)" | while read line; do grep -e "${line}" genome.gff >> suspicious.gff; done

Running it as a script also produces an empty file: 作为脚本运行它还会生成一个空文件:

#!/bin/bash
SUSP=$1
GFF=$2

while read -r line; do
        grep -e "${line}" $GFF >> suspicious_bee_genes.gff
done<$SUSP

This is what the files look like: 这是文件的样子:

head genome.gff
##gff-version 3
#!gff-spec-version 1.21
#!processor NCBI annotwriter
#!genome-build Amel_4.5
#!genome-build-accession NCBI_Assembly:GCF_000002195.4
##sequence-region NC_007070.3 1 29893408
##species http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=7460
NC_007070.3 RefSeq  region  1   29893408    .   +   .       ID=id0;Dbxref=taxon:7460;Name=LG1;gbkey=Src;genome=chromosome;linkage-    group=LG1;mol_type=genomic DNA;strain=DH4
NC_007070.3 Gnomon  gene    181 211962  .   -   .   ID=gene0;Dbxref=BEEBASE:GB42164,GeneID:726912;Name=cort;gbkey=Gene;gene=cort;gene_biotype=protein_coding
NC_007070.3 Gnomon  mRNA    181 71559   .   -   .   ID=rna0;Parent=gene0;Dbxref=GeneID:726912,Genbank:XM_006557348.1,BEEBASE:GB42164;Name=XM_006557348.1;gbkey=mRNA;gene=cort;product=cortex%2C transcript variant X2;transcript_id=XM_006557348.1

wc -l genome.gff
457742

head suspicious.txt
gene10002
gene1001
gene1003
gene10038
gene10048
gene10088
gene10132
gene10134
gene10181
gene10209

wc -l suspicious.txt
928

Does anyone know what's going wrong here? 有人知道这是怎么回事吗?

This can happen when the input file is in DOS format: each line will have a trailing CR character at the end, which will break the matching. 当输入文件为DOS格式时,可能会发生这种情况:每行的末尾都有一个CR字符,这将破坏匹配。

One way to check if this is the case is using hexdump , for example (just the first few lines): 检查情况是否如此的一种方法是使用hexdump ,例如(仅前几行):

 $ hexdump -C suspicious.txt 00000000 67 65 6e 65 31 30 30 30 32 0d 0a 67 65 6e 65 31 |gene10002..gene1| 00000010 30 30 31 0d 0a 67 65 6e 65 31 30 30 33 0d 0a 67 |001..gene1003..g| 00000020 65 6e 65 31 30 30 33 38 0d 0a 67 65 6e 65 31 30 |ene10038..gene10| 

In the ASCII representation at the right, notice the .. after each gene. 在右侧的ASCII表示中,注意每个基因后的.. These dots correspond to 0d and 0a . 这些点对应于0d0a The 0d is the CR character. 0d是CR字符。

Without the CR character, the output should look like this: 没有CR字符,输出应如下所示:

 $ hexdump -C <(tr -d '\\r' < suspicious.txt) 00000000 67 65 6e 65 31 30 30 30 32 0a 67 65 6e 65 31 30 |gene10002.gene10| 00000010 30 31 0a 67 65 6e 65 31 30 30 33 0a 67 65 6e 65 |01.gene1003.gene| 00000020 31 30 30 33 38 0a 67 65 6e 65 31 30 30 34 38 0a |10038.gene10048.| 

Just one . 只是一个. after each gene, corresponding to 0a , and no 0d . 在每个基因之后,对应于0a ,没有0d

Another way to see the DOS line endings in the vi editor. vi编辑器中查看DOS行尾的另一种方法。 If you open the file with vi , the status line would show [dos] , or you could run the ex command :set ff? 如果使用vi打开文件,状态行将显示[dos] ,或者可以运行ex命令:set ff? to make it tell you the file format (the status line will say fileformat=dos ). 使它告诉您文件格式(状态行将显示fileformat=dos )。

You can remove the CR characters on the fly like this: 您可以像这样即时删除CR字符:

grep -f <(tr -d '\r' < suspicious.txt) genome.gff

Or you could remove in vi , by running the ex command :set ff=unix and then save the file. 或者,您可以通过运行ex命令:set ff=unixvi删除,然后保存文件。 There are other command line tools too that can remove the DOS line ending. 还有其他命令行工具也可以删除DOS行结尾。

Another possibility is that instead of a trailing CR character, you might have trailing whitespace. 另一种可能性是,您可能会有尾随空白,而不是尾随CR字符。 The output of hexdump -C should make that perfectly clear. hexdump -C的输出应该清楚地表明这一点。 After the trailing whitespace characters are removed, the grep -f should work as expected. 删除结尾的空白字符后, grep -f应该可以按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM