2016-01-05 62 views
0

我試圖把該輸入:合併4條線路在一個

A----A----------A----A-A--AAAA 
-CC----CCCC-C-----CCC-C-------C 
------G----G--G--G------G------ 
---TT--------T-T---------T----- 

成以下的輸出:

ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC 

我想使用bash這一點。有沒有特定的命令來做到這一點,或者我需要寫一個實際的腳本?

+4

您需要編寫一個實際的腳本,您應該自己嘗試這樣做 –

+0

我試過了,當然是 –

+2

然後你的問題就顯示出你的嘗試 –

回答

1

一個可能的解決方案:

#!/bin/bash 
line[1]="A----A----------A----A-A--AAAA-" 
line[2]="-CC----CCCC-C-----CCC-C-------C" 
line[3]="------G----G--G--G------G------" 
line[4]="---TT--------T-T---------T-----" 

lsize=${#line[1]} 
out="" 
for ((i=0; i<$lsize; i++)) ; do 
    for ((j=1; j<=4; j++)) ; do 
     c=${line[${j}]:${i}:1} 
     if [ "$c" != "-" ] ; then 
      out=${out}${c} 
     fi 
    done 
done 
echo $out 

注意,這個假設輸入是良好的形成 - 它確實沒有錯誤檢查! 您不妨使用「讀」或其他方式獲得的四個輸入字符串,例如:

#!/bin/bash 
read line[1] < a.dat 
read line[2] < c.dat 
read line[3] < g.dat 
read line[4] < t.dat 
... 

如果所有4線輸入的是在一個單一的文件,你可以重定向標準輸入和使用:

#!/bin/bash 
read line[1] 
read line[2] 
read line[3] 
read line[4] 
+0

非常感謝,幫助。 –

+0

@VitalVerleyen如果這回答你的問題,請將其標記爲已回答。謝謝。 –

+1

如果你對這些數組進行硬編碼,你可以跳過腳本並自己寫出序列。 – 123

0

的Perl

perl -ne ' 
    if ($. == 1) {$str = $_; next} 
    for (my $i=0; $i<length($str); $i++) { 
     substr($str,$i,1) = substr($_,$i,1) if substr($_,$i,1) =~ /[ACGT]/; 
    } 
    END {print $str} 
' file 

在AWK相同程序

awk ' 
    NR == 1 {str = $0; next} 
    { 
     for (i=1; i<=length($0); i++) 
      if (substr($0,i,1) ~ /[ACGT]/) 
       str = substr(str,1,i-1) substr($0,i,1) substr(str,i+1) 
    } 
    END {print str} 
' file 
0

如果第一行用-結束,這awk命令應該爲你工作:

awk 'NR==1{split($0,a,"");next} 
    {delete b;split($0,b,"") 
      for(i=1;i<=length(a);i++)if(a[i]=="-") a[i]=b[i] 
    } 
    END{for(i=1;i<=length(a);i++)printf "%s",a[i];print ""}' file 

測試與您的數據:

kent$ cat f 
A----A----------A----A-A--AAAA- 
-CC----CCCC-C-----CCC-C-------C 
------G----G--G--G------G------ 
---TT--------T-T---------T----- 

kent$ awk 'NR==1{split($0,a,"");next} 
     {delete b;split($0,b,"") 
       for(i=1;i<=length(a);i++)if(a[i]=="-") a[i]=b[i] 
     } 
     END{for(i=1;i<=length(a);i++)printf "%s",a[i];print ""}' f 
ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC 
+0

也可以做'awk -F'''{for(i = 1; i <= NF; i ++)$ i!〜/ -/&& a [i] = $ i} END {for(i = 1; i < = NF; i ++)printf a [i]; print y}'' – 123

1

另一個腳本沒有錯誤檢查(和循環)

$ fold -w1 file | pr -4t | sed 's/\s*-\s*//g' | tr -d '\n' | sed '$a\' 

ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC 

ps。您的第一行最後缺少-

另一個短替代

fold -w1 file | pr -4t | tr -d '\n\t\- ' | sed '$a\' 
+0

最後一個sed是什麼?與摺疊PR組合也很好! – 123

+0

最後的sed在字符串的末尾添加一個換行符。 – karakfa

0

這可能會爲你工作(GNU SED):

sed -r ':a;N;s/^/\n/;tb;:b;s/\n+$//;ta;s/\n-(.*\n)(.)/\2\n\1/;tb;s/\n(.)(.*\n)./\1\n\2/;tb' file 

這個解決方案取決於是否等長的都行,但是它適用於線中的任意量。

模式空間中收集兩行,並在第一行的前面插入換行符。然後,第一行中的每個字符與同一位置中第二行中的一個字符匹配,如果它是' - ',則交換。但是,如果它不是' - ',它將被單獨留下,並且下一個字符被匹配,直到遇到每個字符(第二行縮短一個,第一行中的位置被一個字符碰撞。剩下匹配的是換行符,然後換行符被刪除,如果存在另一行,它會被附加到當前行並重復該過程。