Глобальная замена Perl затрагивает каждый файл - как это остановить? - PullRequest
1 голос
/ 23 августа 2010

Я использовал это для обновления каждого файла в каталоге

perl -pi -e 's/include\s?\(/include_once(/g' *.php

Работает нормально, но, похоже, изменяет дату доступа для каждого файла * .php в каталоге - есть ли способ, которым я могу заставить его изменять только доступ к дате тех файлов, которые он фактически изменил?

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

Я предполагаю, что вы имеете в виду время модификации, а не время доступа.

Я делаю это, выбирая, какие файлы обновлять:

egrep -l 'include\s?\(' *.php | xargs perl -pi -e ...
1 голос
/ 23 августа 2010

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