Есть ли способ автоматизации изменения имен файлов в тегах <link>, <script> - PullRequest
1 голос
/ 12 сентября 2010

когда мы используем заголовок Expires для текстовых файлов, таких как js, css, содержимое кэшируется в браузере, чтобы получить новое содержимое, нам нужно изменить в html-файле новые имена в теге link и script. Когда мы добавим изменения. Как мы можем автоматизировать это.

В Windows Box у меня может быть несколько html-файлов в нескольких папках, также в подкаталогах.

Там будет текстовый файл

filelist.txt

OldName                 NewName
oldfile1-ver-1.0.js      oldfile1-ver-2.0.js  
oldfile2-ver-1.0.js      oldfile2-ver-2.0.js  
oldfile3-ver-1.0.js      oldfile3-ver-2.0.js  
oldfile4-ver-1.0.js      oldfile4-ver-2.0.js  

Скрипт должен изменить все oldfile1-ver-1.0.js на oldfile1-ver-2.0.js в HTML-файлах php

Я бы запустил этот скрипт, прежде чем начать загрузку.

Наконец, скрипт может создать список файлов и номер строки, где он произвел обновление.

Решение может быть в Perl / PHP / BATCH или во всем, что приятно и элегантно

Ответы [ 3 ]

2 голосов
/ 12 сентября 2010

Почти наверняка есть более элегантные решения, но этот хак из командной строки выполняет свою работу.

$ perl -i ~ -pe 's / ver-1.0.js / ver-2.0.js / g '* .html

Это внесет изменения во все html-файлы в текущем каталоге.И у вас будет набор резервных файлов с расширением .html ~.

1 голос
/ 12 сентября 2010

В приведенном ниже коде используется Perl редактирование на месте , позволяющее изменять только те файлы, которые необходимо изменить, и оставляет резервные копии оригиналов. Например, если он обновляет foo.php, оригинал будет в foo.php.bak.

Начнем с типичного фронта. Мы будем использовать модуль File :: Find для поиска файлов HTML и PHP на любой глубине, начиная по умолчанию в текущем каталоге или во всех каталогах, указанных в командной строке.

#! /usr/bin/perl

use warnings;
use strict;

use File::Find;

sub usage { "Usage: $0 [ directory .. ]\n" }

В read_filelist мы получаем список преобразований, использующих их для генерации двух битов кода:

  1. скомпилированное регулярное выражение, соответствующее любой строке, содержащей хотя бы одно старое имя файла, и
  2. скомпилированная подпрограмма, которая заменяет старые имена новыми.

Обратите внимание на использование \b, которое соответствует только на границах слов, и quotemeta, которое экранирует любые метасимволы регулярных выражений. Они ограничивают замены только буквальными вхождениями старых имен файлов.

Это немного длинно, так что простите полосу прокрутки.

sub read_filelist {
  my $path = "filelist.txt";
  open my $fh, "<", $path
    or die "$0: open $path: $!";

  my $code = q[
    sub {
      while (<>) {
  ];

  my @old;
  my $errors;
  while (<$fh>) {
    next if $. == 1 && /OldName.*NewName/;

    my($old,$new) = split;
    unless (defined($old) && defined($new)) {
      warn "$0: $path:$.: missing filename\n";
      ++$errors;
    }

    my($qmold,$qmnew) = map quotemeta($_) => $old, $new;
    $code .= "        s/\\b$qmold\\b/$qmnew/gi;\n";

    push @old, $old;
  }

  die "$0: will not continue\n" if $errors;

  $code .= q[        print; 
      }
    }];

  local $@;
  print $code, "\n";
  my $sub = eval $code;
  die "$0: should not happen: $@" if $@;

  my $pattern = '\b(' .
                join("|", map quotemeta, @old) .
                ')\b';

  #print $pattern, "\n";
  my $regex = eval { qr/$pattern/oi };
  die "$0: should not happen: $@" if $@;

  ($regex, $sub);
}

Здесь мы запоминаем корневые каталоги для начала поиска и читаем filelist.txt. Редактирование на месте в Perl требует, чтобы обновляемые файлы находились в специальном массиве @ARGV.

my @dirs = @ARGV ? @ARGV : ".";
my($has_old,$replace) = read_filelist;

Подпункт needs_update - это рабочий, который File::Find::find использует для проверки необходимости изменения данного файла. Мы можем поместить все файлы PHP и HTML в @ARGV, но в случаях, когда код ничего не меняет, вы все равно получите файлы резервных копий для всего.

sub needs_update {
  return unless /\.(?:php|html)$/i;

  open my $fh, "<", $_
    or warn("$0: open $_: $!"), return;

  while (<$fh>) {
    if (/$has_old/) {
      push @ARGV, $File::Find::name;
      return;
    }
  }
}, 

Для основного события мы очищаем @ARGV, используем needs_update, чтобы добавить соответствующие файлы PHP и HTML, и раскрыть скомпилированную подпрограмму на них.

# set up in-place editing
@ARGV = ();
find \&needs_update, @dirs;

die "$0: nothing to do!\n" unless @ARGV;
$^I = ".bak";
$replace->();

__END__

Пара заметок:

  • Приведенный выше код пытается выполнить все замены в порядке, указанном в filelist.txt.
  • Он не пытается ограничить область видимости элементами <link> и <script>. Чтобы сделать это правильно, требуется анализатор HTML. Если имена источников Javascript в filelist.txt иногда не следует заменять, я могу обновить этот ответ дополнительным механизмом, но выполнение добавит еще больше кода.

В Windows вставьте код (без моего текущего комментария) в файл с расширением .pl, а затем запустите его как

C:\> fixjs.pl

для исправления файлов HTML и PHP под текущим каталогом. Чтобы обработать один или несколько каталогов в другом месте, запустите

C:\> fixjs.pl D:\some\dir E:\another
0 голосов
/ 13 сентября 2010

Почему бы не изменить свою систему так, чтобы ваши файлы были шаблонами, а затем использовать библиотеку, например Template Toolkit, для выбора файлов во время сборки. Вы также можете управлять информацией о развертывании таким же образом.

Было бы просто иметь цель make, которая копирует ваши необработанные файлы и применяет обработку шаблонов на основе данных конфигурации, сохраненных в файле или извлеченных из среды.

...