2015-10-09 109 views
0

的亞型我有以下格式的大文件:一個基因的LINUX awk命令合併基因

chr1 11873 12227 DDX11L1 . + 
chr1 12612 12721 DDX11L1 . + 
chr1 13220 14409 DDX11L1 . + 
chr1 14361 14829 WASH7P . - 
chr1 14969 15038 WASH7P . - 
chr1 15795 15947 WASH7P . - 
chr1 16606 16765 WASH7P . - 
chr1 16857 17055 WASH7P . - 
chr1 17232 17368 WASH7P . - 
chr1 17368 17436 MIR6859-2 . - 
chr1 17368 17436 MIR6859-1 . - 
chr1 17605 17742 WASH7P . - 
chr1 17914 18061 WASH7P . - 
chr1 18267 18366 WASH7P . - 
chr1 24737 24891 WASH7P . - 
chr1 29320 29370 WASH7P . - 
chr1 34610 35174 FAM138A . - 
chr1 34610 35174 FAM138F . - 
chr1 35276 35481 FAM138A . - 
chr1 35276 35481 FAM138F . - 
chr1 35720 36081 FAM138A . - 
chr1 35720 36081 FAM138F . - 
chr1 69090 69093 OR4F5 . + 
chr1 69090 70005 OR4F5 . + 
chr1 69090 70008 OR4F5 . + 
chr1 70005 70008 OR4F5 . + 
chr1 134772 139696 LOC729737 . - 
chr1 139789 139847 LOC729737 . - 

我想合併所有亞型的座標(coloumn 4)。 如果第四列中的值在列中相同,我希望第一個匹配行的第2列中的值和最後一個匹配行中第3列的值相同,因此輸出將變爲。

chr1 11873 14409 DDX11L1 . + 
chr1 14361 29370 WASH7P . - 
chr1 17368 17436 MIR6859-2 . - 
chr1 17368 17436 MIR6859-1 . - 
chr1 34610 36081 FAM138A . - 
chr1 34610 36081 FAM138F . - 
chr1 69090 70008 OR4F5 . + 
chr1 134772 139847 LOC729737 . - 

在此先感謝您,期待您的積極響應。

+1

你爲什麼要標記awk/sed?在問題中我看不到awk或sed代碼。 - 其實我根本沒有看到任何問題。 – melpomene

+0

我認爲有可能使用awk命令來獲得所需的輸出 – learner

+0

您應該至少已經學會了如何格式化第一個問題的樣本輸入/輸出。 –

回答

2

我假設你想要最小的col2和最大的col3。

sort -k4 -k2n| 
awk '$4!=p4{if(NR>1)print p1,min,max,p4,p5,p6; 
      p1=$1;min=$2;max=$3;p4=$4;p5=$5;p6=$6;} 
    $4=p4{if($3>max)max=$3} 
    END{print p1,min,max,p4,p5,p6}'| 
sort -k2n 
+0

非常感謝。有效。 – learner

3

使用此awk

awk '!a[$4]{b[i++]=$0} {a[$4]=$3} END{for(i in b){$0=b[i];$3=a[$4];print}}' file 
  • !a[$4]:適用於每一個在第四字段中顯示第一行
    • b[i++]=$0:在這種情況下,填充陣列b與這些線
  • {a[$4]=$3}適用於每一行。數組a填充第三個字段,完成後存儲第三個字段的最後一個值。當所有行被處理
    • for(i in b)環槽陣列b
    • END{...}將被執行。
    • $0=b[i]設置$0可變
    • $3=a[$4]的第三字段應該是最後一次出現
    • print打印行

輸出:

chr1 11873 14409 DDX11L1 . + 
chr1 14361 29370 WASH7P . - 
chr1 17368 17436 MIR6859-2 . - 
chr1 17368 17436 MIR6859-1 . - 
chr1 34610 36081 FAM138A . - 
chr1 34610 36081 FAM138F . - 
chr1 69090 70008 OR4F5 . + 
chr1 134772 139847 LOC729737 . - 

如果你想它columnated,使用此:

awk ... | column -t 
+0

這是巧妙的。但請注意,它在打印之前會將整個輸出存儲在內存中。取決於「大」的大小,那裏有一個潛在的缺陷。 –

+0

@JeffY是的,這是真的,但我沒有別的辦法。該文件可能在第一行有第一個出現,最後一行出現在最後(理論上)。因此,我們必須在打印任何內容之前循環整個文件... – chaos

+0

確實如此,除非您可以使用保證穩定的外部排序(而不是更改等密鑰記錄的順序)對數據進行預處理。我假設學習者真的想要min2和max3,而不是我的解決方案中的first2和last3。但是現在我發現Unix(cygwin)排序實際上是外部的,並且還有一個-s stable選項,所以即使是O(1)內存中的first2/last3也是可能的,如果這是學習者真正需要的...... –

1

這可能會爲你工作(GNU sed和排序):

sort -sk4,4 file | 
sed -r ':a;$!N;s/^((\S+\s+){2})\S+\s+(\S+)\s+.*\s+(\S+\s+\3)/\1\4/;ta;P;D'| 
sort -sk2,2n 

排序第四列的文件,但保留原來的訂購。

一次讀取兩行,將具有匹配第四列的行縮減爲一行,並保留最後一行的第三列。

將上述過程的輸出按第二列數字排序(再次保留原始順序)。