2008-11-21 147 views
1

我有一个Perl脚本的问题。它修改一个文件的内容,然后重新打开它来写,并在这个过程中丢失了一些字符。从'%'开始的所有单词都将从文件中删除。这很烦人,因为%表达式是对话框的可变占位符。为什么我的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"; 

回答

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 
4

尔。你正在使用printf。

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

改为使用“打印”。

如果非要用printf,用

printf "%s", $content; 

重要提示:

的printf表示打印格式,只是因为它在C.

fprintf中是用于文件IO的C等价物。

Perl是不是C.

,甚至在C,将您的内容作为参数1让你拍出于安全原因。

0

甚至

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

-e说: “有下列代码,您可以运行”

-i李明博说, “重命名旧文件whatever.bak”

-p增加围绕-e代码的读取打印循环Perl单行程是一个强大的工具,可以为您节省大量的苦差事。

+0

不,-i bak说“将旧文件重命名为nothingbak”。 whatever.bak将是-i .bak – ysth 2008-11-23 10:11:16

0

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

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

那是因为你使用的printf代替打印,你知道的printf不打印“%”(因为它会觉得你忘记输入格式符号,例如%s,%f等),除非您明确提到“%%”。 :-)

相关问题