问题描述
我有一个程序,该程序在内部配置了许多文件名.该程序将编辑与数据库帐户关联的一堆配置文件,然后更改该数据库帐户的数据库密码.
I have a program that has a number of filenames configured internally. The program edits a bunch of configuration files associated with a database account, and then changes the database password for the database account.
配置文件列表通过内部列表与数据库帐户的名称相关联.处理这些文件时,我的程序中存在以下循环:
The list of configuration files is associated with the name of the database account via an internal list. When I process these files, I have the following loop in my program:
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?我很困惑.
The problem is, this writes the modified output to STDOUT, not CONFIGFILE. How do I get this to actually edit inplace? Move the $^I inside the loop? Print CONFIGFILE? I'm stumped.
>
更新:我在PerlMonks上找到了 一个>.您可以在循环内使用本地ARGV以常规Perl方式进行就地编辑.上面的循环现在看起来像:
Update: I found what I was looking for on PerlMonks. You can use a local ARGV inside the loop to do inplace editing in the normal Perl way. The above loop now looks like:
foreach (@{$Services{$request}{'files'}})
{
my $filename = $Services{$request}{'configDir'} . '/' . $_;
print "Processing ${filename}\n";
{
local @ARGV = ( $filename);
while (<>)
{
s/$oldPass/$newPass/;
print;
}
}
}
如果不是一开始就使用configDir,我可以将整个列表扔到本地@ARGV中,但这足够有效.
If it weren't for tacking the configDir on the beginning, I could just toss the whole list into the local @ARGV, but this is efficient enough.
感谢有关Tie::File
的有用建议.如果这样做了,我可能会走那条路.我正在编辑的配置文件的长度从不超过几KB,因此Tie不会使用过多的内存.
Thanks for the helpful suggestions on Tie::File
. I'd probably go that way if doing this over. The configuration files I'm editing are never more than a few KB in length, so a Tie wouldn't use too much memory.
推荐答案
File::Slurp
提供方便的功能edit_file
和edit_file_lines
.您的代码的内部看起来应该是:
The recent versions of File::Slurp
provide convenient functions, edit_file
and edit_file_lines
. The inner part of your code would look:
use File::Slurp qw(edit_file);
edit_file { s/$oldPass/$newPass/g } $filename;
这篇关于需要Perl在命令行上就地编辑文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!