Из любопытства я написал редактор на месте с намерением надежно обрабатывать все имена файлов и пытаться избежать проблем с длиной командной строки оболочки. Программа ниже берет один или несколько каталогов (по умолчанию текущий каталог, если ни один из них не указан) и создает find ... | xargs ...
конвейер, который пытается выдать @ARGV
только те источники 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;
}
На данный момент, @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)