【发布时间】:2014-11-28 04:38:10
【问题描述】:
我正在尝试找出一种方法来加快模式搜索并在两个大文本文件 (>10Mb) 之间进行替换。 File1 有两列,每行都有唯一的名称。 File2 有一列包含 File1 中的一个共享名称,没有特定的顺序,下面的一些文本跨越可变数量的行。它们看起来像这样:
File1:
uniquename1 sharedname1
uqniename2 sharedname2
...
File2:
>sharedname45
dklajfwiffwf
flkewjfjfw
>sharedname196
lkdsjafwijwg
eflkwejfwfwf
weklfjwlflwf
我的目标是使用 File1 将 sharedname 变量替换为它们对应的唯一名称,如下:
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 改进的 sed 命令所花费的时间:
time sed -f <(sed -E 's|(.*) (.*)|s/^\2/>\1/|' File1 | tr "\n" ";") File2
real 21m43.555s
user 21m41.780s
sys 0m1.140s
【问题讨论】:
-
如果一个共享名在 File2 中只出现一次,在第一次替换后尝试 sed 上的
q命令停止读取 -
你可能会觉得这很有趣:unix.stackexchange.com/a/137932/24557
-
感谢运行时间比较!它表明 Perl 脚本的速度几乎是 Bash 脚本的 70 倍。
-
这几乎没有意义,但 Perl 脚本实际上只需要不到 2 秒,而 sed 命令需要超过 2100 倍!
标签: bash perl sed parallel-processing fasta