sed正则表达式匹配非空格或制表符

时间:2013-03-20 11:57:44

标签: regex sed grep

我正在尝试解析看起来像这样的输入:

i171_chr1_C_MSTA_K0.184_full    i266_chr1_+_MSTA_K0.195_full    92.06   2255    125 21  1   2221    2235    1   0.0 3123
i172_chr1_+_MLT1D_K0.575_full   i172_chr1_+_MLT1D_K0.575_full   100.00  2290    0   0   1   2290    1   2290    0.0 4229
i172_chr1_+_MLT1D_K0.575_full   i172_chr1_+_MLT1D_K0.575_full   100.00  2290    0   0   1   2290    1   2290    0.0 4229

所需的输出是:

i171 1 i266 1 92
i172 1 i172 1 100
i172 1 i172 1 100

换句话说,我在第一列“_”之前提取名称,在第二列之后将部分提取到第二列(类似于第三和第四列)。

我编写的命令适用于前四列:

grep -v "#" blastGE90_lengthGE1000 | cut -f 1,2 | sed -r 's/(.+)_chr([0-9XY]+)_.+\t(.+)_chr([0-9XY]+).+/\1 \2 \3 \4/'

但是,当我尝试在输入中匹配第三列时,我没有成功。我总是匹配最后一场比赛而不是我想要的比赛:

grep -v "#" blastGE90_lengthGE1000 | cut -f 1,2 | sed -r 's/(.+)_chr([0-9XY]+)_.+\t(.+)_chr([0-9XY]+).+([0-9]+\.).+/\1 \2 \3 \4 \5/' 

因此,我想使用regexp来匹配非空格或制表符,但我无法弄明白。

2 个答案:

答案 0 :(得分:3)

我修好了你的命令:

grep -v "#" blastGE90_lengthGE1000 | cut -f 1-3 | sed -r 's/(.+)_chr([0-9XY]+)_.+\t(.+)_chr([0-9XY]+)_.+\t([0-9]+).+/\1 \2 \3 \4 \5/'

您需要使用cut -f 1-3而不是cut -f 1,2,因为您需要前三列。 我还修复了sed表达式中的最后一个捕获组。

答案 1 :(得分:1)

我会在这里使用awk

$ awk -F'_| +' '{gsub(/chr/,"");print $1,$2,$7,$8,int($13)}' file
i171 1 i266 1 92
i172 1 i172 1 100
i172 1 i172 1 100