我用它来更新目录中的每个文件
perl -pi -e 's/include\s?\(/include_once(/g' *.php
它工作正常,但它似乎修改了目录中每个* .php文件的访问日期 - 有没有办法让它只修改它实际修改过的那些文件的日期访问?
答案 0 :(得分:2)
我假设您的意思是修改时间,而不是访问时间。
我通过选择要更新的文件来做到这一点:
egrep -l 'include\s?\(' *.php | xargs perl -pi -e ...
答案 1 :(得分:1)
出于好奇,我写了一个就地编辑器,目的是强健地处理所有文件名,并试图避免shell命令行长度问题。下面的程序需要一个或多个目录(如果没有指定,则默认为当前目录)并创建一个find ... | xargs ...
管道,试图仅为那些需要调整的PHP源提供@ARGV
。
#! /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;
}
此时,@ARGV
可能为空,如果是,我们会保释。
unless (@ARGV) {
warn "$0: nothing to do\n";
exit 1;
}
否则,我们会模仿-i
开关的处理,该开关必须经过<>
和print
。代码至少会警告错误,例如文件系统空间不足而不是静默失败。
# $^I = ""; # no backup
$^I = ".bak";
while (<>) {
s/include\s*\(/include_once(/g;
print;
}
continue {
if (eof) {
close ARGV or warn "$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)