在非常大的文件中快速替换文本

在非常大的文件中快速替换文本

我有 25GB 的文本文件,只需要替换几行字符串。我可以sed成功使用,但是需要很长时间才能运行。

sed -i 's|old text|new text|g' gigantic_file.sql

有没有更快的方法来做到这一点?

答案1

你可以试试:

sed -i '/old text/ s//new text/g' gigantic_file.sql

由此参考:

优化速度:如果需要提高执行速度(由于输入文件较大或处理器或硬盘速度较慢),如果在给出“s/.../.find”表达式之前指定了“find”表达式,则替换将执行得更快。 ../“ 操作说明。

这是一个 10G 文件的比较。前:

$ time sed -i 's/original/ketan/g' wiki10gb
real    5m14.823s
user    1m42.732s
sys     1m51.123s

后:

$ time sed -i '/ketan/ s//original/g' wiki10gb
real    4m33.141s
user    1m20.940s
sys     1m44.451s

答案2

简短的回答是“否” - 此类操作的限制因素是磁盘 IO。没有任何方法可以更快地传输 25GB 的磁盘。如果您不就地编辑,并且将结果写入sed单独的驱动器(如果有可用的驱动器),您可能会得到一个小小的改进 - 因为这样您可以从一个驱动器读取,同时写入另一个驱动器,并且有一点从而减少争用。

可能能够通过不对每一行使用正则表达式引擎来加快速度 - 例如使用 perl (我很确定你可以这样做,sed但我不知道语法) - 这将从第 10,000 行开始向前。

perl -pe '$. > 10_000 && s/old_text/new_text/g' 

如果 RE(元字符)中存在任何类型的复杂情况,那么将这些问题最小化轻微地提高正则表达式引擎的效率。

答案3

如果新旧文本的长度相同,您可以查找文件并仅写入更改的字节,而不是复制整个文件。否则您将陷入移动大量数据的困境。

注意:这很棘手,需要编写自定义代码。

如果您使用 C 或 C++,或者您喜欢的用于搜索和写入系统调用的语言包装器,请参阅 fseek 的手册页。

如果您坚持仅使用命令行,并且可以获得文本的字节偏移量,则可以使用仔细编写的“dd”命令将替换文本写入到位。

相关内容