Perl在一个大文本文件中多次搜索和替换操作

时间:2017-07-04 13:33:13

标签: bash perl

在文件replacements.txt中给出一组替换字符串,如

s/string1/replacement1/g;
s/string2/replacement2/g;
s/string3/replacement3/g;
s/string4/replacement4/g;
s/string5/replacement5/g;

我想获得相当于

的内容
sed -f replacements.txt infile.txt 

我的文件太大了sed无法处理它,而我知道perl可以解决这个问题。

此外,替换品确实很多,并且不时变化。 (我需要运行十几次)

请注意,替换是固定字符串,所以我真的不需要那些是正则表达式。

sed仅在regexp包含整数且输入文件为单个大行时才出现问题。

1 个答案:

答案 0 :(得分:3)

perl命令的 sed相当于:

perl -p replacements.txt infile.txt

如果replacements.txt语句正确s - 终止,它应与您的示例;一起使用(请注意sed会自行识别该行的结尾作为陈述终结者)。

真正的问题是,整个大文件是单行 ,因此避免内存不足的关键是:

  • 暂时将该行分成许多短行,
  • 通过管道发送这些短线并对它们执行字符串替换,
  • 然后重新加入修改后的短线以再次形成一行。

如果数据中的某个字符分隔记录(数据单位),则在不会干扰字符串替换的位置,打破长在tr 的帮助下划分为多个是一种可行的方法;我将以}为例,因为Kuzeko声明数据类似于JSON:

如果你有 GNU sed (Linux;请与sed --version核实):

tr '}' '\0' < infile.txt | sed -z -f replacements.txt | tr '\0' '}'

tr输出NUL - 分隔&#34;行&#34; (\0)和sed相应地读取它们(-z)是处理分块的最有效方法。
不幸的是,-z / --null-data选项不符合POSIX,BSD / macOS实现支持它。

否则(例如,在 macOS 上):

tr '}' '\n' < infile.txt | perl -p replacements.txt infile.txt | tr '\n' '}'

警告:如果infile.txt中的单行有一个尾随\n,那么您最终会得到额外的}个字符。在末尾;要防止这种情况,请在删除 tr的管道中添加一个初始\n阶段:
tr -d '\n' < infile.txt | tr '}' '\n' | ...

perl仍然需要,因为 - 与BSD / macOS sed不同 - 它保留了输入最后一行的尾随 - \n - 或 - 无状态。< / p>