grep或awk匹配一行和以下特定模式

时间:2013-02-15 13:06:21

标签: awk grep

我已经开始使用linux机器,我正在尝试做一些简单的事情......但对我来说非常困难。 我需要选择一些与第二个文件中报告的行匹配的特定行。 实际上我有一个第一个文件是这样的:

>aba19  EN1 enl.or11    http://mar2043  annotation not avaliable
MASESEMGVVASJDHAGISFGVDDASDASDAFGDFGHWFACFQLIGIFLAYCLSRAITNN
QSDHKAJSDHKASJHKJAHKHKJSDGHYEIV
>clat38 EN2 enl.o   http://mar20s/Gene/Summary?5    annotation not avaliable
MNCEDCHILNAEAFKSKKDASDADICKSLKICGLVFGILALTLIVLFWGSKHFWPEVPKK
AYDMEHTFYSNGERGYCCASDSDDIYCSDRRGNRYCRRVCEPLLGYYPYPYCYQGGRVIC
RVIMPCDASDASDAOPWEIPQWFHNDJBVHAOISDOUIAODGNWWVARMLGRV
>coll9  EN4 ens4    http://mar2010.arch/Genary?g=E9 annotation not avaliable
MASKALDHLFKLJLÒFJASDJKLASDLAFJLFJFJLFJLAJFLKJFLAKFJFJLAFJLAL
ASDLASKDJASLKDJASLKJFALSKDJALKDJSKLDJLSDKJASLDKJSLDKSDLAKJKS
SILDUAISDALSDJALKDJASDLFATT 
>hihi9  EN9 ens44   http://mar2010.ariens/Geary?g=EN7   annotation not    avaliable
MGSLDLAÈPWOEMWBZMKSJDHAJKSDHAKSDHSDHSDHOASDAKSJDHKASJDHAAKHL
KTLSDKLHRFSDFHPHFGCJLJLJRKKFLDSFCGTVGEFAGGGDTHNNVCLSSVFVSEDG
HSDFSDWFKLGGMETVCSDFKVSQATPEFSSSDLFFDSRIQSIRDPASIPPEEMSPEFTT
LPECHGHARDAFSFGTLVESLLTILNEQVSADVLSSFQQTLHSTLLNPIPKCRPALCTLL
SDFLSDJFKLSDFLSKDFJM

我有第二个文件,其中包含我需要从第一个文件中“提取”的模式列表。第二个文件看起来像这样:

>clat38
>coll9

实际上,我希望得到这样的输出:

>clat38 EN2 enl.o   http://mar20s/Gene/Summary?5    annotation not avaliable
MNCEDCHILNAEAFKSKKDASDADICKSLKICGLVFGILALTLIVLFWGSKHFWPEVPKK
AYDMEHTFYSNGERGYCCASDSDDIYCSDRRGNRYCRRVCEPLLGYYPYPYCYQGGRVIC
RVIMPCDASDASDAOPWEIPQWFHNDJBVHAOISDOUIAODGNWWVARMLGRV
>coll9  EN4 ens4    http://mar2010.arch/Genary?g=E9 annotation not avaliable
MASKALDHLFKLJLÒFJASDJKLASDLAFJLFJFJLFJLAJFLKJFLAKFJFJLAFJLAL
ASDLASKDJASLKDJASLKJFALSKDJALKDJSKLDJLSDKJASLDKJSLDKSDLAKJKS
SILDUAISDALSDJALKDJASDLFATT

我尝试了grep -f file_2 file_1 > output,但我只得到了这个:

>clat38
>coll9

我可以为grep添加更具体的内容吗? 谢谢你的建议! 加布

4 个答案:

答案 0 :(得分:2)

要在一行中搜索正则表达式,请使用grep。从手册页和几个例子中学习它。

要将字符串替换为单行上的正则表达式,请使用sed。从手册页和几个例子中学习它。

对于所有其他文本处理应用程序,请使用awk。从“有效的Awk编程,第三版”一书中学习,作者:Arnold Robbins,http://www.oreilly.com/catalog/awkprog3/

awk 'NR==FNR{a[$0];next} $1 in a{c=2} c&&c--' file2 file1

如果要在找到所需的密钥时打印超过2行,只需将c的值更改为3或20或其他。

鉴于您的评论如下以及您更新的示例输入,这应该是您想要的:

awk 'NR==FNR{a[$0];next} /^>/{f=0} $1 in a{f=1} f' file2 file1

答案 1 :(得分:1)

来自grep联机帮助页:

-A NUM, --after-context=NUM
          Print NUM  lines  of  trailing  context  after  matching  lines.
          Places  a  line  containing  --  between  contiguous  groups  of
          matches.

所以在这种情况下,只需添加-A1即可。

从评论中,更好的解决方案是:

grep -xFA1 -f file_2 file_1 | grep -v "^\--"

-x匹配整行

-F将模式视为字符串而不是正则表达式

我必须添加第二个grep语句来删除额外的行。

答案 2 :(得分:0)

一个awk单行应该适合你:

awk 'NR==FNR{a[$0];next}{x=$0;getline;if(x in a)print x"\n"$0}' file2 file1

kent$  head file1 file2
==> file1 <==
>aba19
 ALKSDJASDKASDLKASDL
>clat38
 PDASODJADASLDKALSKDLACASDLKAJ
>coll9
 AOSODADALSDKALDKASLDSAK
>hihi9
 JHASDASDJOASDJAOSD

==> file2 <==
>clat38
>coll9

kent$  awk 'NR==FNR{a[$0];next}{x=$0;getline;if(x in a)print x"\n"$0}' file2 file1
>clat38
 PDASODJADASLDKALSKDLACASDLKAJ
>coll9
 AOSODADALSDKALDKASLDSAK

答案 3 :(得分:0)

awk 'FNR==NR{a[$0];next}{for(i in a)if(i==$0){print;getline;print}}' second_file first_file

测试如下:

> cat temp
>aba19
 ALKSDJASDKASDLKASDL
>clat38
 PDASODJADASLDKALSKDLACASDLKAJ
>coll9
 AOSODADALSDKALDKASLDSAK
>hihi9
 JHASDASDJOASDJAOSD

> cat temp2
>clat38
>coll9

> awk 'FNR==NR{a[$0];next}{for(i in a)if(i==$0){print;getline;print}}' temp2 temp
>clat38
 PDASODJADASLDKALSKDLACASDLKAJ
>coll9
 AOSODADALSDKALDKASLDSAK
>