1

これは、Perl スクリプト自体から perl を実行する冗長なようです。

my $Pref = "&*())(*&^%$#@!"; 
system("perl -pi -e 's|^SERVERNAME.*\$|SERVERNAME \"\Q$Pref\E\"|g' pserver.prefs");

-pi を模倣する実際の Perl コードは何ですか? Perl の sed のように機能するものを、できる限りシンプルにしたいだけです。


Todd Gardner のサイトに基づくと、基本的にすべてのファイルを読み書きし、すべての行に正規表現を適用しようとしているようです。この解決策は、私のような初心者の Perl ユーザーにとっては少し複雑だったので、以下を使用して単純化しました。

my $ftp = "/home/shared/ftp";
my $backup = $ftp . ".bak";
rename($ftp, $backup);
open (FTP, "<", $backup) or die "Can't open $backup: $!"; 
open (FTP_OUT, ">", $ftp) or die "Can't open $ftp: $!"; 
    while (<FTP>)
    {
        $_ =~ s|$panel_user \Q$panel_oldpass\E |$panel_user \Q$panel_newpass\E |g;
        print FTP_OUT $_;
    }
close(FTP);
close(FTP_OUT);

2つのオープンを使用すると何か問題がありますか? これは避けるべきですか、それとも単純な解決策で問題ありませんか?

システムの sed コマンドの方がはるかにシンプルでクリーンであることは認めざるを得ません。

4

4 に答える 4

8

オプションの詳細を説明しているperlrunをチェックしてください。特に、いくつかのオプションが用意されています。

シェルから、言って

$ perl -p -i.orig -e "s/foo/bar/; ... "

プログラムを使用するのと同じです:

#!/usr/bin/perl -pi.orig
s/foo/bar/;

これは

#!/usr/bin/perl
$extension = '.orig';
LINE: while (<>) {
if ($ARGV ne $oldargv) {
    if ($extension !~ /\*/) {
    $backup = $ARGV . $extension;
    }
    else {
    ($backup = $extension) =~ s/\*/$ARGV/g;
    }
    rename($ARGV, $backup);
    open(ARGVOUT, ">$ARGV");
    select(ARGVOUT);
    $oldargv = $ARGV;
}
s/foo/bar/;
}
continue {
print;  # this prints to original filename
}
select(STDOUT);
于 2009-06-29T05:16:06.490 に答える
6

Tie::Fileを使用します。

use Tie::File;
use File::Copy;

copy $file, "$file.bak" or die "Failed to copy $file to $file.bak: $!";
tie @array, "Tie::File", $file or die "Can't open $file: $!";
s/foo/bar/ for @array;
于 2009-06-29T07:33:22.173 に答える
4

Perlmonksには、次と同等の提案があります。

use English qw<$INPLACE_EDIT>;

{
    local ($INPLACE_EDIT, @ARGV) = ('.bak', @files);   
    while (<>) {
        s/this/that/;
        print;       
    }
}

同じスレッドでSysadm::Install::pieも推奨されます

于 2009-06-29T13:41:51.633 に答える
4

B::Deparseあなたの友達です:

cowens@amans:~/test$ perl -MO=Deparse -pi -e 1
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    print $_;
}
-e syntax OK

$^Iこのことから、それがインプレース編集を実装していることがわかります。@ARGV編集したいファイルに設定し、ループするだけです。

于 2009-06-29T13:46:57.457 に答える