fgrep -f还输出string_file中匹配的字符串

时间:2015-01-14 23:26:04

标签: bash unix grep

我正在使用命令:

fgrep -wf string_file.txt searching_file.txt > myoutput.txt

(在下面的例子中,为了简单起见,我只提供了很少的值,但是请假设可能还有更多的值)

-f用于指定基于search_file.txt中搜索的string_file

-w用于执行基于单词的搜索,并消除两个文件之间的分数匹配。

string_file.txt包含:

DEFB106A
ZXFGH456
ANKRD23
FNTDRE2433

searching_file.txt包含:

1553970_s_at    carboxyl ester lipase (bile salt-stimulated lipase) /// bile salt-activated lipase
1552411_at  defensin, beta 106A /// defensin, beta 106B, DEFB106A /// DEFB106B
1555890_at  olfactory receptor, family 2, subfamily A, member 20 pseudogene /// OR2A20P /// OR2A9P
1553366_s_at    ankyrin repeat domain 23 /// ankyrin repeat domain 39, ANKRD23 /// ANKRD39  
1554894_a_at    pterin-4 alpha-carbinolamine dehydratase/dimerization cofactor of hepatocyte PCBD2
1555286_at  cyclin-dependent kinase-like 1 (CDC2-related kinase), CDKL1

此次运行的输出是:myoutput.txt

1552411_at  defensin, beta 106A /// defensin, beta 106B, DEFB106A /// DEFB106B
1553366_s_at    ankyrin repeat domain 23 /// ankyrin repeat domain 39, ANKRD23 /// ANKRD39

由于搜索到的字符串(来自string_file的用于执行搜索的字符串)经常被发现被埋没了#39;在线的中间,例如:" DEFB106A"在这条线的中间:

1552411_at  defensin, beta 106A /// defensin, beta 106B, **DEFB106A** /// DEFB106B
  • 我基本上有兴趣从sting_file为每个输出行分配自己的原始字符串,以便我能够轻松识别search_file.txt文件中哪些搜索字符串产生匹配。
  • 或者,换句话说,这里的想法是从埋藏它的原始线中提取匹配的字符串。同时,我还需要整个上下文(所以我也有兴趣输出整个匹配的行,因为它包含我需要的值,例如probeset ID,例如1552411_at)。
  • 这里的想法也是为了让我们能够识别来自string_file.txt的哪些字符串在searching_file.txt中有匹配!

例如,作为输出,我希望得到这样的东西:

1552411_at  defensin, beta 106A /// defensin, beta 106B, DEFB106A /// DEFB106B    DEFB106A 
1553366_s_at    ankyrin repeat domain 23 /// ankyrin repeat domain 39, ANKRD23 /// ANKRD39  ANKRD23 

OR

DEFB106A 1552411_at defensin, beta 106A /// defensin, beta 106B, DEFB106A /// DEFB106B    
ANKRD23 1553366_s_at    ankyrin repeat domain 23 /// ankyrin repeat domain 39, ANKRD23 /// ANKRD39  

注意,很多情况如ZXFGH456和FNTDRE2433(来自string_file)都不会产生任何匹配。

1 个答案:

答案 0 :(得分:3)

您可以使用grep对此sed的输出进行后处理 - 假设您有Bash和process substitution

$ grep -Fwf string_file.txt searching.txt |
>     sed -f <(sed 's%.*%s/.*\\(\\<&\\>\\).*/\\1 \&/%' string_file.txt) 
DEFB106A 1552411_at  defensin, beta 106A /// defensin, beta 106B, DEFB106A /// DEFB106B
ANKRD23 1553366_s_at    ankyrin repeat domain 23 /// ankyrin repeat domain 39, ANKRD23 /// ANKRD39
$

内部sed命令将string_file.txt文件转换为一系列sed命令;内部sed的输出是:

s/.*\(\<DEFB106A\>\).*/\1 &/
s/.*\(\<ZXFGH456\>\).*/\1 &/
s/.*\(\<ANKRD23\>\).*/\1 &/
s/.*\(\<FNTDRE2433\>\).*/\1 &/

\<\>是老派的表示法,sed的某些版本支持标记单词的开头和结尾。在实践中,你可能没有这些,除非你需要搜索列表中另一个单词的子串的单词(因此,如果你需要搜索ABCDABCDEF,结束标记是必要的。)

sed脚本输出通过流程替换提供给外部sed,并对grep的输出进行后处理(grep -F相当于fgrep })生成所需的输出。

如果一行中出现多个术语,则会将它们全部推到前面。如果这是一个问题,有很多方法,但它们并不是特别整洁(尽管大多数问题来自使用sed生成sed脚本)。

在Ubuntu 14.04衍生产品上进行测试。