使用 Perl 在文件中搜索和替换多个 "foo" 和 "bar"? SED 太慢

search and replace multiple "foo" and "bar" in a file using Perl? SED is too slow

我有一个非常大的文本文件(超过 4GB)。我有多个条目要在这个巨大的文件中搜索和替换 (pattern.txt)。

所以,我编写了一个名为 leo.sed 的文件并使用了 sed -f 命令。

leo.sed:该文件包含大约 500 个条目。 示例:

s/"PET10"/"PETfdfd0"/g
s/"PET11"/"PET123wef"/g
s/"PET12"/"TETPrandom"/g


我正在使用以下 sed 命令,但它非常慢。

sed -f leo.sed pattern.text | sed -f leo1.sed > pattern_after_leo_leo1_sed.txt

使用 perl one-liner 有没有更快的方法?

如果它只需要做一次,如果它“足够快”,设置它 运行 并做其他事情。 Your time is more valuable than the computer's.


如果您受限于您的磁盘速度,您将无能为力。

如果不是,同样的技术,每行做 500 个模式,在 Perl 中不太可能更快。相反,您需要改进算法。需要减少正则表达式的数量。这可以通过找到一些常见的模式来完成。

例如,如果它是引号中的所有内容,我们可以使用一个匹配引号中任何内容的正则表达式。然后替换值来自哈希。我们在 BEGIN 块中设置哈希,以便在扫描文件之前只执行一次。我们可以使用 babycart operator 在字符串中插入表达式。

perl -i.orig -pe 'BEGIN { %replacements = (PET10 => "PETfdfd0", PET11 => "PET123wef"); } s{"([^"]+)"}{"@{[$replacements{} || ]}"}g' test.txt

现在每行只需要扫描一次。这可能会或可能不会更快。

这是 Schwern 发布的代码的更快版本:

perl -i.orig -pe'
   BEGIN {
      %replacements = map qq{"$_"}, (
         PET10 => "PETfdfd0",
         PET11 => "PET123wef",
      );
   }
   s{"[^"]+"}{ $replacements{$&} // $& }eg
' test.txt