2016-09-30 94 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。更新。 –