有没有办法在<link />,<script>标签</script>中自动更改文件名

时间:2010-09-12 11:10:19

标签: windows perl automation batch-file build-automation

当我们对文本文件(如js,css)使用Expires头时,内容会缓存在浏览器中,为了获取新内容,我们需要在html文件中更改链接和脚本标记中的新名称。当我们添加更改时。我们怎样才能使它自动化。

在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 更改为html,php文件中 oldfile1-ver-2.0.js

我会在开始上传之前运行此脚本。

最后,脚本可以创建一个文件列表和行号进行更新。

解决方案可以是Perl / PHP / BATCH或任何美观而优雅的

3 个答案:

答案 0 :(得分:2)

几乎可以肯定更优雅的解决方案,但是这个命令行黑客可以完成工作。

  

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

这将改变当前目录中的所有html文件。并且您将拥有一组扩展名为.html~。

的备份文件

答案 1 :(得分:1)

以下代码使用Perl的in-place editing功能仅修改那些需要更改的文件并保留原始文件的备份。例如,如果它更新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. 使用new替换旧名称的已编译子。
  3. 请注意\b仅使用与单词边界匹配的quotemetasub 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

    在这里,我们记住了开始搜索和阅读@ARGV的根目录。 Perl的就地编辑要求将文件更新为特殊的my @dirs = @ARGV ? @ARGV : "."; my($has_old,$replace) = read_filelist; 数组。

    needs_update

    File::Find::find@ARGV用来检查是否应修改给定文件的工作者。我们可以将所有PHP和HTML文件放在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,使用# set up in-place editing @ARGV = (); find \&needs_update, @dirs; die "$0: nothing to do!\n" unless @ARGV; $^I = ".bak"; $replace->(); __END__ 添加适当的PHP和HTML文件,并在其上释放已编译的子文件。

    filelist.txt

    几点说明:

    • 上述代码尝试按<link>
    • 中给出的顺序进行所有替换
    • 它不会尝试将范围限制为<script>filelist.txt元素。正确执行此操作需要HTML解析器。如果.pl中的Javascript源名称有时不应该替换,我可以使用额外的机制更新此答案,但这会增加更多的代码。

    在Windows上,将代码(减去我正在运行的评论)粘贴到扩展名为{{1}}的文件中,然后将其作为

    运行
    C:\> fixjs.pl

    修补当前目录下的HTML和PHP文件。要在其他地方处理一个或多个目录,请运行

    C:\> fixjs.pl D:\some\dir E:\another

答案 2 :(得分:0)

为什么不修改您的系统以使您的文件是模板,然后使用像Template Toolkit这样的库来在构建时选择您的文件。您也可以采用相同的方式管理部署特定信息。

使用make目标复制原始文件并根据存储在文件中或从环境中提取的配置数据应用模板处理将是一件简单的事情。