用sed取代巨大的块

时间:2009-09-01 09:32:14

标签: bash scripting sed

我有2个在别处生成的文件。第一个是“搜索什么”,第二个是替换。这两个文件都很庞大,每个文件大约2-3mb。

我需要编写一个bash脚本,它需要一个更大的文件(大约200-300mb)并将所有出现的file1内容替换为file2内容。

问题是,file1和file2可以包含任何可能的字符,包括正则表达式特殊符号。

如何使用sed解决此问题?

提前致谢。

3 个答案:

答案 0 :(得分:1)

由于你实际上并不需要正则表达式,只是直接字符串匹配,sed是过度的。你真正想要的是一个固定字符串(甚至可能是二进制)流编辑器。不幸的是,我不知道一个...我讨厌建议可能重新发明一个轮子,但你可以在C中写一些能够做你想做的事情。粗略草案大纲:

  • 将搜索文件读入内存
  • 创建与search-file相同大小的缓冲区
  • 从stdin(或输入文件)读入缓冲区。
    • 对于每个字符,如果它与search-file中的并行字符不匹配,请移动缓冲区。要找出要移动多少,读取直到找到与输入文件的第一个字符匹配,然后检查其余是否匹配,重复直到找到输入文件的部分匹配(或获取到缓冲区的末尾)。移位时,将所有不匹配的字符打印到stdout(或输出文件)
    • 如果缓冲区填满,即完全匹配输入文件,则将replacement-file打印到stdout(或输出文件)。根据内存与速度的不同,您可以将替换文件保留在内存中或每次从磁盘读取。

您还可以尝试自动转义输入文件中的所有正则表达式字符。这可以通过一个非常难看的sed替换列表来完成,比如

sed -e 's/\\/\\\\/g' -e 's@/@\/@' -e 's/\[/\\[/g' ...

(确保先进行\一次!)

答案 1 :(得分:1)

也许看看chgrep:

http://www.bmk-it.com/projects/chgrep/

干杯,

gregx

答案 2 :(得分:0)

我不知道sed,但在Perl中你可以做到(在我的头顶,未经测试):

perl -0777 -pe 'BEGIN{local $/ = undef; open FROM, "<", shift @ARGV; $from = <FROM>; open TO, "<" shift @ARGV; $to = <TO>} s/\Q$from\E/$to/sog' file1 file2 bigger-file > new-bigger-file

如果你有兴趣尝试Perl,我明天可以尝试为你测试。

但它将整个较大的文件吸收到内存中,因为它忽略了换行符,因此您的搜索文本可以跨越多行。这意味着它会占用大量内存!

此答案假定搜索文件是多行上的一个长搜索字符串,必须完整匹配,而不是多个单独的搜索字符串,其中任何一个都可以匹配。