Awk 用于字符串替换的更快算法/语言 编辑:

Awk 用于字符串替换的更快算法/语言 编辑:,awk,substring,Awk,Substring,下面提供的方法3通过测试更快,将预计运行时间从2-3天减少到40% 将该子字符串中的每个字符替换为N或N(保留 案例) 样本输出: CACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCNNNNNNNCACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNN

下面提供的方法3通过测试更快,将预计运行时间从
2-3
天减少到
<1


我有一个长字符串为50M的示例文件,如下所示

CACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCNNNNNNNCACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgtgtgtatatatcatgtgtgGCCCTAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGatgtgtggtgtgtggggttagggttagggttaNNNNNNNNNNNCCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgtgtgtatataGCCCTAGGtcatgtgtgatgtgtggtgtgtggggttagggttagggttaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCCTAGGNNNNNNNGCCCTAGGNNNNNNNNNNNNNNAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgttggggtNNNNNNGgtgtgtatatatcatagggAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgtggtgtgggtgtgtggggttagggAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtggtgtgtggggttagggttagggttaNNNNNNNNNNNNtgttgttttattttcttacaggtggtgtgtggggttagggttagggttaNNNNNNNNNNNCCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgtgtgtatatatcatgtAGCCCTAGGGatgtgtggtgtgtggggttagggttagggttaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNttgtggtgtgtggtgNNNNNAGGGCtggtgtgtggggttagggAtagggAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgtggtgtgtggggGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgtggtgtgtggggttagggNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGaggcatattgatcCCCTCCAAGGATCaagctCCgaTNNNNNNNggttagggttNNNNNGgtgtCCCTAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgtggtgtgtggggttagggttagggttaNNNNNNNNNNNNtgttgttttattttcttacaggtggtgtgtggggttagggttagggttaNNNNNNNNNNNCCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgtgtgtatatatcatgtAGCCCTAGGGatgtgtggtgtgtggggttagggttagggttaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNttgtggtgtgtggtgNNNNNAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgttggggtNNNNNNGgtgtgtatatatcatagggAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgatgtgtggtgtgggtgtgtggggttagggAGGGCCCTAGGGCCCTAtgtgtgGCCCTAGGGCtgtgtgGCCCTAGGGCGGagtatatatcatgtgtgNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
对于长度为
k=50的所有
子字符串
(这意味着
长度(文件)-k+1
子字符串)

如果
A|T|A|T
(大写和小写)为
>40%

将该子字符串中的每个字符替换为
N
N
(保留 案例)

样本输出:

CACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCNNNNNNNCACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCaagctCCgaTNNNNNNNNNNNNGgnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnggttaNNNNNNNNNNNNNNNNNNNNNNNNnnnnnNNnnNNNNNNNNNNNNNNnnnnnnnnnnnNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGCCCTAGGNNNNNNNGCCCTAGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNNNnnnnnNNnnNNNNNNNNNNNNNNnnnnnnnnnnnnnnnnnNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNttgtggtgtgtggtgNNNNNAGGNNnnnnnnnnnnnnnnnnnnNnnnnnNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnngggttagggNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGaggcatattgatcCCCTCCAAGGATCaagctCCgaTNNNNNNNggttagggttNNNNNGnnnnNNNNNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNNNnnnnnNNnnNNNNNNNNNNNNNNnnnnnnnnnnnnnnnnnNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNttgtggtgtgtggtgNNNNNNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnNNNNNNNNNNNNNNNNNnnnnnnNNNNNNNNNNnnnnnnNNNNNNNNNNNNnnnnnnnnnnnnnnnngNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
为了方便起见,我在命令行中使用了
AWK
。。。并且只消耗chr22.masked.fa cat chr22.fa |尾-n+2 | awk-VK=100-VR=40'{ printf(“chr22.fa:%d\n”,长度($0)) i=1; 而(i r*k/100){ h++ 高gc[i]=i } printf(“索引-r:%f%%高达:%d\r”,i/(长度($0)-k+1)*100,h) i+=1 } printf(“索引-r:%f%%高达:%d\n\n”,i/(长度($0)-k+1)*100,h) 对于(高GC中的j){ y=高GC[j] 潜艇++ printf(“sub-r:%f%%\r”,sub/h*100) x=substr($0,y,k) gsub(/[AGCT]/,“N”,x) gsub(/[agct]/,“n”,x) $0=substr($0,1,y-1)x substr($0,y+k) } printf(“sub-r:%f%%\n替代:%d\n\n”,sub/h*100,sub) printf(“%s”,0美元)>>“chr22.masked.fa” }' #方法2 cat chr22.fa |头-n1>chr22.masked2.fa cat chr22.fa | tail-n+2 | awk-v k=“100”-v r=40'{ printf(“chr22.fa:%d\n”,长度($0)) i=1; h=0; 而(ir/k*100){ h++ gsub(/[GC]/,“N”,x) gsub(/[gc]/,“n”,x) $0=substr($0,1,i-1)x substr($0,i+k) } printf(“索引-r:%f%%sub-r:%f%%\r”,i/(长度($0)-k+1)*100,h/544*100) i+=1 } gsub(/X/,“N”,$0) gsub(/x/,“n”,$0) printf(“索引-r:%f%%sub-r:%f%%\n”,i/(长度($0)-k+1)*100,h/544*100) printf(“%s”,0美元)>>“chr22.masked2.fa” }' #方法3 cat chr22.fa |头-n1>chr22.masked3.fa cat chr22.fa | tail-n+2 | awk-v k=“100”-v r=40'{ printf(“chr22.fa:%d\n”,长度($0)) i=1; h=0; 而(i r/k*100){ h++ gsub(/[ACGT]/,“N”,x) gsub(/[acgt]/,“n”,x) 如果(i==1){ s=x }否则{ s=substr(s,1,长度-k+1)x } }否则{ 如果(i==1){ s=x }否则{ s=s substr(x,k,1) } } printf(“索引-r:%f%%sub-r:%f%%\r”,i/(长度($0)-k+1)*100,h/544*100) i+=1 } printf(“索引-r:%f%%sub-r:%f%%\n\n”,i/(长度($0)-k+1)*100,h/544*100) printf(“%s”,s)>>“chr22.masked3.fa” }'
预计运行时间约为2-3天

这个问题有没有更快的算法?如果没有,是否有任何语言可以更快地执行字符串替换

更多信息:
AWK
命令在
WSL
GitBash
上消耗
~30%的CPU,但在windows
cmd
OpenSSH
客户机上只消耗
~5%
的CPU,在该客户机上,进度速度类似好的,有一个
O(n)
解决方案涉及到数据集上的滑动窗口。以下算法应足够:

set window to ""
while true:
    if window is "":
        read k characters into window, exit while if less available
        set atCount to number of characters in window matching "AaTt".
    if atCount > 40% of k:
        for each char in window:
            if char uppercase:
                output "N"
            else:
                output "n"
        window = ""
    else:
        if first character of window matches "AaTt":
            decrease atCount
        remove first character of window
        read next character into end of window, exit while if none available
        if last character of window matches "AaTt":
            increase atCount
这样做的目的是在数据中运行一个滑动窗口,在每个点测试
AaTt
字符在该窗口中的比例是否超过40%

如果是,则输出所需的
Nn
字符,并重新加载下一个k大小的窗口

如果不超过40%,它将删除窗口中的第一个字符,并将下一个字符添加到末尾,从而正确调整
AaTt
字符的计数

如果在任何时候,没有足够的字符来满足检查(
k
加载完整窗口时,或
1
滑动时),它将退出循环。

尝试一些perl:

perl-slpe'
my$len=长度;
对于(我的$i=0;$i<$len;$i+=k){
my$substring=substr($\u,$i,$k);
我的$count=$substring=~tr/aAtT/aAtT/;
如果($count>=$k*$threshold){
$substring=~s/[:lower:]/n/g;
$substring=~s/[:upper:]/N/g;
substr($\$i,$k)=$substring;
}
}
'--k=50-阈值=0.4文件

Edited,这是我使用的更简单的方法。我尝试过的另一个类似方法是在linkCode中,比如
$0=substr($0,1,I-1)x substr($0,I+k)
很可能会非常昂贵,而且
printf()
每个字符似乎都过多。如果此代码有效,则将其发布到通常更好。就我个人而言,我已经用Python重写了这个问题。我投票结束这个问题,因为它应该打开。
printf()
用于跟踪这个问题的进展。。。我把代码运行了6个小时,不知道什么时候会结束。我将在代码审查中重新发布相同的问题,谢谢。@thanasisp结果应该是
nnnn
,因此我的代码将用
x
替换所有
a
,首先,在计算百分比时包括
x
的计数,最后用
n
替换所有
x
,我尝试了这种方法,并在代码链接中实现,这在我的问题中并不重要。速度的关键要素是重写输入字符串
$0=substr($0,1,i-1)x substr($0,i+k)
@hey0god:我不确定
awk
是否是这项工作的最佳工具,而字符串替换可能也没有多大帮助(在速度部门)。如果您想坚持使用简单的脚本语言,Python可能是一个更好的选择。否则,C或C++对原始速度可能会更好。
set window to ""
while true:
    if window is "":
        read k characters into window, exit while if less available
        set atCount to number of characters in window matching "AaTt".
    if atCount > 40% of k:
        for each char in window:
            if char uppercase:
                output "N"
            else:
                output "n"
        window = ""
    else:
        if first character of window matches "AaTt":
            decrease atCount
        remove first character of window
        read next character into end of window, exit while if none available
        if last character of window matches "AaTt":
            increase atCount