Perl全局替换涉及每个文件-如何停止?
我用它来更新目录中的每个文件Perl全局替换涉及每个文件-如何停止?,perl,Perl,我用它来更新目录中的每个文件 perl -pi -e 's/include\s?\(/include_once(/g' *.php 它工作正常,但似乎修改了目录中每个*.php文件的访问日期-有没有办法让它只修改实际修改的文件的访问日期?我假设您指的是修改时间,而不是访问时间 我通过选择要更新的文件来完成此操作: egrep -l 'include\s?\(' *.php | xargs perl -pi -e ... 出于好奇,我编写了一个就地编辑器,目的是健壮地处理所有文件名,并试图避免
perl -pi -e 's/include\s?\(/include_once(/g' *.php
它工作正常,但似乎修改了目录中每个*.php文件的访问日期-有没有办法让它只修改实际修改的文件的访问日期?我假设您指的是修改时间,而不是访问时间 我通过选择要更新的文件来完成此操作:
egrep -l 'include\s?\(' *.php | xargs perl -pi -e ...
出于好奇,我编写了一个就地编辑器,目的是健壮地处理所有文件名,并试图避免shell命令行长度问题。下面的程序获取一个或多个目录(如果未指定任何目录,则默认为当前目录),并创建一个
find…|xargs…
管道,它试图只提供需要调整的PHP源代码
#! /usr/bin/perl
use warnings;
use strict;
BEGIN {
@ARGV = (".") unless @ARGV;
my $xargspid = open my $xargs, "-|";
die "$0: fork: $!" unless defined $xargspid;
my @paths;
if ($xargspid) {
local $/ = "\0";
while (<$xargs>) {
chomp;
push @paths => $_;
}
unless (close $xargs) {
my $status = $? >> 8;
die "$0: xargs exited $status"
if $status != 0 && $status != 123;
}
}
else {
my $findpid = open my $find, "-|";
die "$0: fork: $!" unless defined $findpid;
if ($findpid) {
open STDIN, "<&", $find or die "$0: dup find: $!";
exec "xargs", "--null", "egrep", "-lZ", 'include[[:space:]]*\('
or die "$0: exec xargs: $!";
}
else {
exec "find", @ARGV, "-maxdepth", 1,
"-name", "*.php",
"-print0"
or die "$0: exec find: $!";
}
}
@ARGV = @paths;
}
否则,我们将模拟-i
开关的处理,该开关必须经过
和打印
。该代码至少会对文件系统空间不足等错误发出警告,而不是无声地失败
# $^I = ""; # no backup
$^I = ".bak";
while (<>) {
s/include\s*\(/include_once(/g;
print;
}
continue {
if (eof) {
close ARGV or warn "$0: close $ARGV: $!\n";
}
}
#$^I=“”#没有备份
$^I=“.bak”;
而(){
s/include\s*\(/include\u一次(/g;
印刷品;
}
继续{
如果(eof){
关闭ARGV或警告“$0:close$ARGV:$!\n”;
}
}
样本运行:
$ ./fixinc
$ ls *.php
bar.php baz.php foo.php
$ ls *.bak
bar.php.bak foo.php.bak
$ diff -ub foo.php.bak foo.php
--- foo.php.bak
+++ foo.php
@@ -1 +1 @@
-include(foo)
+include_once(foo)
$ diff -ub bar.php.bak bar.php
--- bar.php.bak
+++ bar.php
@@ -1 +1 @@
-include (bar)
+include_once(bar)
美元/固定汇率公司
$ls*.php
bar.php baz.php foo.php
$ls*.bak
bar.php.bak foo.php.bak
$diff-ub foo.php.bak foo.php
---foo.php.bak
+++foo.php
@@ -1 +1 @@
-包括(foo)
+包括_一次(foo)
$diff-ub bar.php.bak bar.php
---bar.php.bak
+++bar.php
@@ -1 +1 @@
-包括(酒吧)
+include_once(bar)为了安全,最好使用egrep-lZ…| xargs-0,这样带空格的文件名就不会引起问题。那太好了,谢谢。我使用了…egrep-l'include?('*.php | xargs perl-pi-e's/include\s?(/include_once)(/g'-0…它工作得很好。如果您不想让它修改每个PHP文件,请不要告诉它修改每个PHP文件。perl无法知道文件在完成所有行并将它们写入新文件之前不会有这种模式。 $ ./fixinc $ ls *.php bar.php baz.php foo.php $ ls *.bak bar.php.bak foo.php.bak $ diff -ub foo.php.bak foo.php --- foo.php.bak +++ foo.php @@ -1 +1 @@ -include(foo) +include_once(foo) $ diff -ub bar.php.bak bar.php --- bar.php.bak +++ bar.php @@ -1 +1 @@ -include (bar) +include_once(bar)