我正在使用命令:
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
例如,作为输出,我希望得到这样的东西:
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)都不会产生任何匹配。
答案 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
的某些版本支持标记单词的开头和结尾。在实践中,你可能没有这些,除非你需要搜索列表中另一个单词的子串的单词(因此,如果你需要搜索ABCD
和ABCDEF
,结束标记是必要的。)
此sed
脚本输出通过流程替换提供给外部sed
,并对grep
的输出进行后处理(grep -F
相当于fgrep
})生成所需的输出。
如果一行中出现多个术语,则会将它们全部推到前面。如果这是一个问题,有很多方法,但它们并不是特别整洁(尽管大多数问题来自使用sed
生成sed
脚本)。
在Ubuntu 14.04衍生产品上进行测试。