内联处理文件时的perl内存使用情况

时间:2014-08-21 13:15:27

标签: perl

我有一个CGI脚本,我们的员工使用这个脚本从他们无法直接访问的服务器中获取日志。由于我不能进入的原因,在最近更新我们的应用程序之后,这些日志中的一些现在具有诸如换行符,制表符,反斜杠等字符,这些字符被翻译成它们的文本等价物。因此,我修改了CGI脚本以调用以下内容将它们转换回原始值:

perl -i -pe 's/\\r/\r/g && s/\\n/\n/g && s/\\t/\t/g && s/\\\//\//g' $filename

我刚刚获悉有些人在尝试获取相当大的日志(几百MB)时会出现内存不足错误。

我的问题:当调用这样的内联命令时,perl如何管理内存?是读取整个文件,处理它,然后写出来,还是创建一个临时文件,一次处理输入文件中的行,然后一旦完成就替换文件?

这是在64位Amazon Linux实例上使用perl 5.10.1。

1 个答案:

答案 0 :(得分:2)

-p开关创建一个while(<>){...; print}循环来迭代输入文件中的每个“行”。

如果您的所有换行都已转换为"\\n",那么您的文件将只是一条很长的行。因此,您的命令将整个文件加载到内存中以执行修复。

为避免这种情况,您必须使用sysread$/故意缓冲文件。

最简单的方法是创建一个实际的脚本而不是单行来完成工作。但是,如果您知道所有换行都已转换,那么一个简单的解决方法就是使用$/ = "\\n"

作为次要说明,你的正则表达式是有缺陷的。您目前正在使用快捷键操作符列出您的翻译s///。如果任何一个早期的正则表达式与特定行不匹配,则不会尝试其他任何翻译。您应该使用简单的分号来分隔您的正则表达式:

's/\\r/\r/g; s/\\n/\n/g; s/\\t/\t/g; s|\\/|/|g'