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