在最后一场比赛后添加一条线和字符

时间:2015-04-09 16:56:32

标签: regex linux awk sed

我有一个文件,我需要在一行(3位数字)的最后一个匹配后添加一行(和几个字符)。数据按(许多)基因编号(122,239,...)分组,每个基因可能有不同数量的个体。

cat test

122_mex1 TGCAGGC
122_mex2 TGCAGTC
122_mex3 TGCAGTC
122_can4 TGCATTT
239_mex1 TGCAAAA
239_mex2 TGCAAAA
239_can4 TGCAGCA
...
567_can4 TGCAAAT

输出应如下所示:

cat output

122_mex1 TGCAGGC
122_mex2 TGCAGTC
122_mex3 TGCAGTC
122_can4 TGCATTT
//|1
239_mex1 TGCAAAA
239_mex2 TGCAAAA
239_can4 TGCAGCA
//|2

etc.

然后如何找到每个基因编号的最后一个匹配开始每一行并附加一些字符的行,向上计数(1,2,3等)?

我找到了一种在提供的匹配(例如122)之后附加一行的方法

awk '/122/{seen++} seen && !/122/{print "//|1"; seen=0} 1' test

但是id喜欢附加所有基因编号(122,239,455,234等),循环基因并在下一行附加每个连续的基因编号" // i"。

有关如何开始的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:3)

这样可以解决问题:

$ awk -F_ 'NR>1 && last!=$1{print "//|"++i}{last=$1}1' test
122_mex1 TGCAGGC
122_mex2 TGCAGTC
122_mex3 TGCAGTC
122_can4 TGCATTT
//|1
239_mex1 TGCAAAA
239_mex2 TGCAAAA
239_can4 TGCAGCA
//|2
...
//|3
567_can4 TGCAAAT

要保存结果,请使用shell重定向:

$ awk -F_ 'NR>1 && last!=$1{print "//|"++i}{last=$1}1' test > output

答案 1 :(得分:1)

您可以使用awk

awk -F_ 'p!=""{p=$1;next} p != $1 {p=$1; print "//|" ++i} 1; END{print "//|" ++i}' test
122_mex2 TGCAGTC
122_mex3 TGCAGTC
122_can4 TGCATTT
//|1
239_mex1 TGCAAAA
239_mex2 TGCAAAA
239_can4 TGCAGCA
//|2

<强>解释

-F_                     # set field separator as _
p!=""{p=$1;next}        # first time if p is not set, set p=$1 and move to next line
p != $1                 # if 1st field is != previous value of 1st field
{p=$1; print "//|" ++i} # set p=$1 and print divider line with an incrementing var
1;                      # default action to print each record
END{print "//|" ++i}    # END block to print divider line last time