2016-09-30 160 views
0

我有一个制表符分隔的数据框,最后一列包含嵌套信息,即'|'分隔。需要注意的是所有行维持由“REP =”后面这种嵌套的括号结构将嵌套列拆分为多列UNIX

col1 col2 col3 col4 
ID1  text text text...REP=(info1|info2|info3) 
ID2  text text text...REP=(info1|info2|info3) 

我想处理此最后一列,使得括号内的所有信息是新列:

col1 col2 col3 col4 newcol newcol2 newcol3 
ID1  text text text info1  info2  info3 
ID2  text text text info1  info2  info3 

我会认为一个AWK命令会很有用,但是在适当地构造这个命令时遇到了麻烦。任何帮助将非常感激。

+0

REP之前的那些点是否真的存在,还是代表更多列? –

+0

...代表col4中发生在'REP ='之前的其他文本 – AMS

+0

“REP”之前是否存在选项卡? –

回答

1

perl一个衬里,虽然

$ cat ip.txt 
col1 col2 col3 col4 
ID1  text text text REP=(info1|info2|info3) 
ID2  text text text REP=(info1|info2|info3) 

$ perl -pe 's/\s*REP=\(([^)]+)\)/"\t".$1=~tr#|#\t#r/e' ip.txt 
col1 col2 col3 col4 
ID1  text text text info1 info2 info3 
ID2  text text text info1 info2 info3 
  • \s*REP=\(([^)]+)\)零个或多个空格,随后REP(随后捕获组来提取比)其他字符和最后一个)不修改标头
  • e修饰符允许在替换部分使用Perl代码
  • $1=~tr#|#\t#r变化|到从所捕获的基团,其然后被连接到串含有标签
+0

当我尝试运行此代码时,出现以下错误 - 在-e行1处发现了字符,其位于-e行1附近的s/\ |/\ t/gr“ 语法错误”在“s/\ |/\ t/gr附近” 执行-e因编译错误而中止。 – AMS

2

awk来救援!

$ awk -v OFS='\t' 'NR==1{nh=NF; header=$0; next} 
         {v=$NF; 
         sub(/.*REP=/,"",v); 
         sub(/\.\.\.REP=.*/,"",$NF); 
         gsub(/[()]/,"",v); 
         n=split(v,vs,"|"); 
         for(i=1;i<=n;i++) $(NF+i)=vs[i]} 
        NR==2{printf "%s", header; 
         for(i=1;i<=n;i++) printf "%s", OFS "col"(nh+i); 
         print ""}1' file | column -t 

col1 col2 col3 col4 col5 col6 col7 
ID1 text text text info1 info2 info3 
ID2 text text text info1 info2 info3 
+0

非常感谢! – AMS

+1

不要急于接受答案; upvote很好,如果你再等一会儿,也许会有更好的解决方案。我没有多少考虑就把它当做速度编程练习。 – karakfa

+0

不是缩进风格的粉丝,但这只是我如何实现它。 –

0

这确实在端部留下一个标签的标签,但可以固定一个额外GSUB。

awk 'NR==1 {print $0,"col4\tnewcol\tnewcol2\tnewcol3")} NR>1 {gsub(/...REP=\(|\||\)/, "\t");print}' input.txt 
+0

您只需更新第一行的标题,而不是每一行:'awk'NR == 1 {print $ 0,“\ tnewcol1 ...”} NR> 1 {gsub(/ REP .../.. );打印}'' –

+0

谢谢,@glennjackman。更新。 –