Need Perl inplace editing of files not on command line

后端 未结 3 591
小蘑菇
小蘑菇 2020-12-17 14:42

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

相关标签:
3条回答
  • 2020-12-17 15:38

    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;
    
    0 讨论(0)
  • 2020-12-17 15:39

    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;
    }
    
    0 讨论(0)
  • 2020-12-17 15:39

    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:

    • Open a file for input
    • Open a temp file for output
    • Read a line from input file.
    • Modify the line in whatever way you like.
    • Write the new line out to your temp file.
    • Loop to next line, etc.
    • Close input and output files.
    • Rename input file to some backup name, such as appending .bak to filename.
    • Rename temporary output file to original input filename.

    This is essentially what goes on behind the scenes with the -i.bak switch anyway, but with added flexibility.

    0 讨论(0)
提交回复
热议问题