我试图想办法加快模式搜索并替换两个大文本文件(> 10Mb)。 File1有两列,每行都有唯一的名称。 File2有一列包含File1中的一个共享名称,没有特定的顺序,下面有一些文本跨越可变数量的行。他们看起来像这样:
File1:
uniquename1 sharedname1
uqniename2 sharedname2
...
File2:
>sharedname45
dklajfwiffwf
flkewjfjfw
>sharedname196
lkdsjafwijwg
eflkwejfwfwf
weklfjwlflwf
我的目标是使用File1将sharedname变量替换为相应的uniquename,如下所示:
New File2:
>uniquename45
dklajfwif
flkewjfj
>uniquename196
lkdsjafwij
eflkwejf
这是我迄今为止所尝试过的:
while read -r uniquenames sharednames; do
sed -i "s/$sharednames/$uniquenames/g" $File2
done < $File1
它有效,但它的速度非常慢,在这些大文件中跋涉。 CPU使用率是限速步骤,因此我尝试将修改并行使用我可以使用的8个内核,但无法使其工作。我也尝试将File1和File2分成更小的块并同时批量运行,但我也无法实现这一点。你会如何并行实现这个?或者您是否看到了不同的做法?
欢迎任何建议。
更新1
优秀!感谢@Cyrus和@JJoao以及其他评论员提出的建议。我在我的脚本中实现了两个,在@JJoao的推荐下测试计算时间,它是一个改进(约3小时而不是〜5)。但是,我只是在进行文本文件操作,所以我不知道它应该花费多少时间。所以,我仍然在努力更好地利用可用的CPU,所以我在修改建议,看看能不能进一步加快速度。
更新2:更正为更新1 我将修改包含在我的脚本中并按原样运行,但是我的一大块代码正在减慢它的速度。相反,我在目标中间文件上单独运行建议的代码位。这就是我所看到的:
Time for @Cyrus' sed to complete
real 70m47.484s
user 70m43.304s
sys 0m1.092s
Time for @JJoao's Perl script to complete
real 0m1.769s
user 0m0.572s
sys 0m0.244s
看起来我将使用Perl脚本。感谢大家的帮助!
更新3 这是@ Cyrus&#39;改进的sed命令:
time sed -f <(sed -E 's|(.*) (.*)|s/^\2/>\1/|' File1 | tr "\n" ";") File2
real 21m43.555s
user 21m41.780s
sys 0m1.140s
答案 0 :(得分:4)
使用GNU sed和bash:
sed -f <(sed -E 's|(.*) (.*)|s/>\2/>\1/|' File1) File2
<强>更新强>:
试图加快速度:
sed -f <(sed -E 's|(.*) (.*)|s/^>\2/>\1/|' File1 | tr "\n" ";") File2
答案 1 :(得分:2)
#!/usr/bin/perl
use strict;
my $file1=shift;
my %dic=();
open(F1,$file1) or die("cant find replcmente file\n");
while(<F1>){ # slurp File1 to dic
if(/(.*)\s*(.*)/){$dic{$2}=$1}
}
while(<>){ # for all File2 lines
s/(?<=>)(.*)/ $dic{$1} || $1/e; # sub ">id" by >dic{id}
print
}
我更喜欢@cyrus解决方案,但如果您需要经常这样做,您可以使用以前的perl脚本(chmod + install)作为 dict-replacement命令。
用法:dict-replacement File1 File* > output
如果你能告诉我们各种解决方案的时间,那就太好了......