为什么我的Perl脚本会从文件中删除字符?

时间:2008-11-21 10:56:02

标签: perl file

我在使用Perl脚本时遇到了一些问题。它修改文件的内容,然后重新打开以写入文件,并在此过程中丢失一些字符。所有以'%'开头的单词都将从文件中删除。这很烦人,因为%表达式是对话框的可变占位符。

你知道为什么吗?源文件是具有默认编码的XML

以下是代码:

undef $/;
open F, $file or die "cannot open file $file\n";
my $content = <F>;                                           
close F;                                                     

$content =~s{status=["'][\w ]*["']\s*}{}gi;

printf $content;

open F, ">$file" or die "cannot reopen $file\n";             
printf F $content;                                           
close F or die "cannot close file $file\n";

5 个答案:

答案 0 :(得分:26)

你在那里使用printf,它认为它的第一个参数是一个格式字符串。有关详细信息,请参阅printf documentation。当我遇到这种问题时,我总是确保我正确使用这些功能。 :)

您可能只需要print

 print FILE $content;

在您的示例中,您不需要读取整个文件,因为您的替换不会跨行。不要试图一次读取和写入相同的文件名,而是使用临时文件:

open my($in),  "<", $file       or die "cannot open file $file\n";
open my($out), ">", "$file.bak" or die "cannot open file $file.bak\n";

while( <$in> )
    {
    s{status=["'][\w ]*["']\s*}{}gi;
    print $out;
    }

rename "$file.bak", $file or die "Could not rename file\n";

这也减少了这个命令行程序:

% perl -pi.bak -e 's{status=["\']\\w ]*["\']\\s*}{}g' file

答案 1 :(得分:4)

尔。你正在使用printf。

printf将“%”解释为特殊的东西。

使用“print”代替。

如果必须使用printf,请使用

printf "%s", $content;
  

重要提示:

PrintF代表打印格式,就像在C中一样。

fprintf是C for File IO中的equivelant。

Perl不是C.

即使在IN C中,将您的内容作为参数1也可以出于安全原因而拍摄。

答案 2 :(得分:0)

甚至

perl -i bak -pe 's{status=["\'][\w ]*["\']\s*}{}gi;' yourfiles

-e说“有以下代码供您运行”

-i bak说“将旧文件重命名为whatever.bak”

-p在-e code

周围添加了一个读取打印循环

Perl one-liners是一款功能强大的工具,可以为您节省大量的苦差事。

答案 3 :(得分:0)

如果您想要一个了解文档XML特性的解决方案(即,只删除状态属性,而不是匹配文本内容),您还可以使用XML::PYX

$ pyx doc.xml | perl -ne'print unless /^Astatus/' | pyxw

答案 4 :(得分:0)

那是因为你使用了printf而不是print而且你知道printf不会打印“%”(因为它会认为你忘了键入格式符号,例如%s,%f等),除非你明确提到“% %”。 : - )