使用grep或awk匹配文本

使用grep或awk匹配文本,awk,grep,Awk,Grep,我和grep和awk有问题。我想这是因为我的输入文件包含的文本看起来像代码 输入文件包含ID名称,如下所示: SNORD115-40 MIR432 RNU6-2 Ensembl Gene ID HGNC symbol ENSG00000199537 SNORD115-40 ENSG00000207793 MIR432 ENSG00000266661 ENSG00000243133 ENSG00000207447 RNU6-2 ENSG00000199537 SNORD115-40 ENSG0

我和grep和awk有问题。我想这是因为我的输入文件包含的文本看起来像代码

输入文件包含ID名称,如下所示:

SNORD115-40
MIR432
RNU6-2
Ensembl Gene ID HGNC symbol
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000266661
ENSG00000243133
ENSG00000207447 RNU6-2
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000207447 RNU6-2
参考文件如下所示:

SNORD115-40
MIR432
RNU6-2
Ensembl Gene ID HGNC symbol
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000266661
ENSG00000243133
ENSG00000207447 RNU6-2
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000207447 RNU6-2
我希望将源文件中的ID名称与参考文件匹配,并打印出相应的ensg ID号,以便输出文件如下所示:

SNORD115-40
MIR432
RNU6-2
Ensembl Gene ID HGNC symbol
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000266661
ENSG00000243133
ENSG00000207447 RNU6-2
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000207447 RNU6-2
我尝试过这个循环:

exec < source.file
while read line
do
grep -w $line reference.file > outputfile
done
但我只有一个grep的身份证


任何建议或更简单的方法都会很好。

这将实现以下目的:

$ awk 'NR==FNR{a[$0];next}$NF in a{print}' input reference
ENSG00000199537 SNORD115-40
ENSG00000207793 MIR432
ENSG00000207447 RNU6-2
$fgrep-f source.file reference.file
ENSG0000199537 SNORD115-40
ENSG0000207793 MIR432
ENSG0000207447 RNU6-2
fgrep
相当于
grep-F

-F,--固定字符串
将模式解释为固定字符串的列表,由
换行符,任何要匹配的换行符。(-F由
POSIX.)
-f
选项用于从文件中获取
模式

-f FILE,--FILE=FILE
从文件中获取模式,每行一个。空文件
包含零个模式,因此不匹配任何内容。(-f是
由POSIX指定。)
如注释中所述,如果
reference.file
中的ID包含
source.file
中的ID作为子字符串,则可能产生误报。您可以使用
sed
动态地为
grep
构建更明确的模式:


grep-f这是一次很好的
bash
ish尝试。问题是您总是覆盖结果文件。使用“>>”而不是
,或者在
完成后移动

grep -w $line reference.file >> outputfile

但我更喜欢Lev的解决方案,因为它只启动一次外部过程

如果要在纯
bash
中解决此问题,可以尝试以下方法:

ID=($(<IDfile))

while read; do
   for((i=0;i<${#ID[*]};++i)) {
       [[ $REPLY =~ [[:space:]]${ID[$i]}$ ]] && echo $REPLY && break
   }
done <RefFile >outputfile

cat outputfile
较新的
bash
支持关联数组。它可用于简化和加快对密钥的搜索:

declare -A ID
for i in $(<IDfile); { ID[$i]=1;}

while read v; do
   [[ $v =~ [[:space:]]([^[:space:]]+)$ && ${ID[${BASH_REMATCH[1]}]} = 1 ]] && echo $v
done <RefFile
declare-A ID

对于$中的i(这将产生误报,即输入文件中的
SNORD115-40
也将匹配参考ect中的
SNORD115-401
。我们可以使用“fgrep-wf source.file reference.file”来避免误报。