Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要Perl对不在命令行上的文件进行就地编辑吗_Perl_File_In Place - Fatal编程技术网

需要Perl对不在命令行上的文件进行就地编辑吗

需要Perl对不在命令行上的文件进行就地编辑吗,perl,file,in-place,Perl,File,In Place,我有一个程序,内部配置了许多文件名。该程序编辑一组与数据库帐户关联的配置文件,然后更改数据库帐户的数据库密码 配置文件列表通过内部列表与数据库帐户的名称相关联。当我处理这些文件时,我的程序中有以下循环: BEGIN { $^I = '.oldPW'; } # Enable in-place editing ... foreach (@{$Services{$request}{'files'}}) { my $filename = $Services{$request}{'configD

我有一个程序,内部配置了许多文件名。该程序编辑一组与数据库帐户关联的配置文件,然后更改数据库帐户的数据库密码

配置文件列表通过内部列表与数据库帐户的名称相关联。当我处理这些文件时,我的程序中有以下循环:

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;
}
BEGIN{$^I='.oldPW';}#启用就地编辑
...
foreach(@{$Services{$request}{'files'}})
{
my$filename=$Services{$request}{'configDir'}./'.$;
打印“正在处理${filename}\n”;
打开配置文件,'+

更新:我找到了我要查找的内容。您可以在循环中使用本地ARGV以正常的Perl方式进行就地编辑。上面的循环现在看起来像:

foreach (@{$Services{$request}{'files'}})
{
    my $filename = $Services{$request}{'configDir'} . '/' . $_;
    print "Processing ${filename}\n";
    {
        local @ARGV = ( $filename);
        while (<>)
        {
            s/$oldPass/$newPass/;
            print;
        }
    }
}
foreach(@{$Services{$request}{'files'})
{
my$filename=$Services{$request}{'configDir'}./'.$;
打印“正在处理${filename}\n”;
{
local@ARGV=($filename);
而()
{
s/$oldPass/$newPass/;
印刷品;
}
}
}
如果不是为了在开始时添加configDir,我可以将整个列表放到本地@ARGV中,但这已经足够有效了


感谢您对
Tie::File
提出的有用建议。如果再这样做的话,我可能会这样做。我正在编辑的配置文件的长度永远不会超过几KB,因此Tie不会占用太多内存。

使用空变量
$^I
仅对
$ARGV
中保存的文件名序列进行操作ode>
构造。也许类似的东西可以工作:

BEGIN { $^I = '.oldPW'; }  # Enable in-place editing
...

local @ARGV = map {
    $Services{$request}{'configDir'} . '/' . $_ 
} @{$Services{$request}{'files'}};
while (<>) {
   s/$oldPass/$newPass/;

   # print? print ARGVOUT? I don't remember
   print ARGVOUT;
}
最新版本的提供了方便的功能,
edit_file
edit_file_line
。代码的内部看起来:

use File::Slurp qw(edit_file);
edit_file { s/$oldPass/$newPass/g } $filename;

Tie::File已经提到,而且非常简单。对于非命令行脚本,避免使用-i开关可能是一个好主意。如果您希望避免使用Tie::File,标准解决方案是:

  • 打开一个文件进行输入
  • 打开一个临时文件进行输出
  • 从输入文件中读取一行
  • 以您喜欢的任何方式修改该行
  • 将新行写入临时文件
  • 循环到下一行等
  • 关闭输入和输出文件
  • 将输入文件重命名为某个备份名称,例如在文件名后追加.bak
  • 将临时输出文件重命名为原始输入文件名

这基本上就是-i.bak开关在幕后进行的操作,但增加了灵活性。

不要忘记备份文件。实际上,我不需要备份,因为这些文件存储在源代码控制系统中。此脚本的下一步是集成SCC(在本例中为Performce)这样它将在文件更新时签出并提交文件。
use File::Slurp qw(edit_file);
edit_file { s/$oldPass/$newPass/g } $filename;