这似乎是多余的,从Perl脚本本身运行perl。
my $Pref = "&*())(*&^%$#@!";
system("perl -pi -e 's|^SERVERNAME.*\$|SERVERNAME \"\Q$Pref\E\"|g' pserver.prefs");
什么是模仿-pi的实际Perl代码?我只想要一些像Perl上的sed一样的东西,尽可能简单。
基于Todd Gardner的网站,它似乎基本上只是读取和写入所有文件,试图将正则表达式应用于每一行。对于像我这样的noob 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);
使用两个打开有什么问题吗?是应该避免这种情况还是简单的解决方案?
我必须承认,系统sed命令更简单,更清晰。
答案 0 :(得分:8)
查看详细描述选项的perlrun。特别是,它提出了一些选择:
来自shell,说
$ 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);
答案 1 :(得分: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;
答案 2 :(得分:4)
Perlmonks的建议相当于:
use English qw<$INPLACE_EDIT>;
{
local ($INPLACE_EDIT, @ARGV) = ('.bak', @files);
while (<>) {
s/this/that/;
print;
}
}
在同一个帖子中也推荐使用Sysadm::Install::pie
答案 3 :(得分:4)
B::Deparse
是你的朋友:
cowens@amans:~/test$ perl -MO=Deparse -pi -e 1
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
'???';
}
continue {
print $_;
}
-e syntax OK