我有 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”命令将替换文本写入到位。