我有一个在内部配置了多个文件名的程序.该程序编辑与数据库帐户关联的一堆配置文件,然后更改数据库帐户的数据库密码.配置文件的列表通过内部列表与数据库帐户的名称相关联.当我处理这些文件时,我的程序中有以下循环:
BEGIN { $^I = '.oldPW'; } # Enable in-place editing ... foreach (@{$Services{$request}{'files'}}) { my $filename = $Services{$request}{'configDir'} . '/' . $_; print "Processing ${filename}\n"; open CONFIGFILE,'+<',$filename or warn $!; while (<CONFIGFILE>) { s/$oldPass/$newPass/; print; } close CONFIGFILE; }
问题是,将修改的输出写入STDOUT,而不是CONFIGFILE.如何让它实际上编辑在内?在$循环中移动$^ I?打印CONFIGFILE?我被困了
更新:我发现我正在寻找在perlmonks.你可以使用本地ARGV内循环以正常的Perl方式进行在线编辑.上面的循环现在看起来像:
foreach (@{$Services{$request}{'files'}}) { my $filename = $Services{$request}{'configDir'} . '/' . $_; print "Processing ${filename}\n"; { local @ARGV = ( $filename); while (<>) { s/$oldPass/$newPass/; print; } } }
如果不是一开始就要绑定configDir,我可以把整个列表抛到本地的@ARGV里面,但是这样就足够了.
感谢Tie :: File的有用建议,如果这样做,我可能会这样做.我正在编辑的配置文件的长度永远不会超过几KB,所以Tie不会使用太多的内存.
解决方法
最新版本的
File::Slurp
提供了方便的功能,edit_file和edit_file_lines.您的代码的内部部分将会是:
use File::Slurp qw(edit_file); edit_file { s/$oldPass/$newPass/g } $filename;