为什么这个 vim 正则表达式如此消耗资源:s/\n/\\n/g

4
尝试在足够大的文件上执行此操作(例如80,000多行,大小约为500k +)将导致我的服务器和本地Mac崩溃或最终停顿。
我已经尝试在命令行中执行此操作,结果相同:
vim -es -c '%s/\n/\\n/g' -c wq $file

此外,问题似乎出现在选择 (\n) 上,而不是替换 (\\n) 上。
对于我的大文件,我当然可以使用 split 将它们拆分,并在完成后将它们合并,但在我的情况下,拆分点不能是任意的,并且必须手动调整每个拆分点。
我知道还有其他方法可以做到这一点——如 sed 等——但我在那里也遇到了类似的问题,并且我希望能够使用 vim 完成此操作。

2
我的最佳猜测(没有分析vim或regex源代码):替换换行符会改变行数。也许一些代码具有O(n^2)的时间或内存复杂度(撤销缓冲区?)。对于80,000+来说,这是一个很大的n^2。您能监视服务器上vim进程的内存使用情况吗(top、vmstat)? - Jens
好的,我把我的答案搬到这里来了:%s/$/\\n/g 在一条 56K 行 / 16MB 文件上运行得很好,而且速度相当快。 - jingx
跟着加上 %j!,你就能得到和 OP 一样的效果,但可能会更快。 - that other guy
当我尝试使用“80000itest <enter> <esc>:%s / \ n / \ n / g”时,我会遇到内存不足的问题,但我有一个32位版本的gvim。您是使用32位还是64位版本? - Lieven Keersmaekers
我创建了一个大小约为500KB的简单文件,其中包含一个简单的脚本。没有换行符,只有一行。然后我尝试用vim加载该文件。我不得不杀掉它:)。所以我猜测问题在于“大行”而不是替换本身。另一种确认这一点的方法是将\n替换为\n\n。如果速度很快,则问题就是“大行”问题。 - Julio
vim绝对不是这个任务的正确工具。它不适合编辑每行超过五十万个字符的文本文件,而这正是替换后的结果。 - Max
1个回答

2
我将我的评论作为答案添加:
文本编辑器通常不喜欢“巨大”的行(这就是你会得到的替换内容)。为了测试是否是由于“大行”而不是替换本身,我进行了以下测试:我创建了一个简单的约500KB文件与脚本。没有新行字符,只有一行。然后我尝试用vim加载该文件。结果?我不得不杀掉它:-)。
然而,如果在同一个脚本上我每隔一段时间写一些新行,我打开文件时就没有问题。
另外,你可以尝试以下操作:在vim中,将\n替换为\n\n,如果速度很快,那么这也应该确认“大行”问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接