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 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;
The $^I
variable only operates on the sequence of filenames held in $ARGV
using the empty <>
construction. Maybe something like this would work:
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;
}
but if it's not a simple script and you need @ARGV
and STDOUT
for other purposes, you're probably better off using something like Tie::File for this task:
use Tie::File;
foreach (@{$Services{$request}{'files'}})
{
my $filename = $Services{$request}{'configDir'} . '/' . $_;
# make the backup yourself
system("cp $filename $filename.oldPW"); # also consider File::Copy
my @array;
tie @array, 'Tie::File', $filename;
# now edit @array
s/$oldPass/$newPass/ for @array;
# untie to trigger rewriting the file
untie @array;
}
Tie::File has already been mentioned, and is very simple. Avoiding the -i switch is probably a good idea for non-command-line scripts. If you're looking to avoid Tie::File, the standard solution is this:
This is essentially what goes on behind the scenes with the -i.bak switch anyway, but with added flexibility.