在非常大的文件中替换字符串

在非常大的文件中替换字符串

我有一系列很长的没有分隔字符的网址,格式如下:

http://example.comhttp://example.nethttp://example.orghttp://etc...

我希望每个 URL 都换行。我试图通过使用 sed 将“http://”的所有实例替换为“\nhttp://”来做到这一点

sed 's_http://_\nhttp://_g' urls.txt

但发生分段错误(内存违规)。我只能推测文件的绝对大小(超过 100GB)导致 sed 超出了某个限制。

我可以将文件分割成几个较小的文件进行处理,但“http://”的所有实例都需要保持完整。

有一个更好的方法吗?

答案1

有了它,awk您可以避免一次阅读大量文本:

awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt

成功可能取决于所使用的awk实现。例如,gawk工作正常,但mawk崩溃。

答案2

这将完成这项工作:

perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt

通过设置$/,我更改了行的定义,因此它//以换行符结尾。这使得 Perl 一次读取一个 URL。 URL 不太可能包含//except 在方案之后,但如果包含也没关系,正则表达式将阻止它添加虚假的换行符。

如果您想避免在第一个 URL 之前添加空行:

perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt

您可以尝试进行基准测试,看看是否s!http://\z!\nhttp://!更快。它们是等价的。请注意,/g替换时不需要该标志,因为每“行”只能有一个匹配项。

答案3

  1. 将所有出现的 a 更改:为换行符,以分割文件。
  2. 代替
    • http在该行的末尾
    • 换行符后跟http:并附加下一行
  3. 重复一次,偶数行和奇数行都会更新

这些步骤如下所示:

tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
  1. 检查是否有不以 开头的行http://,打印行号。仅当 : 位于 URL 中而不是在http.

    grep -nv '^http://'

相关内容