首页 > 解决方案 > 如何在多个文件中更新 Perl 脚本中的路径

问题描述

我正在创建一些我使用 perl 的培训材料。我想做的一件事是为学生正确设置脚本,无论他们在哪里添加压缩文件。我正在处理一个 Windows 批处理文件,它将 perl 模板复制到工作位置,然后将 perl 模板文件副本中的路径更新到正确的位置。perl 模板将其作为第一行:

#!_BASE_software/perl/bin/perl.exe

批处理文件如下所示:

SET TRAINING=%~dp0
copy %TRAINING%\template\*.pl %TRAINING%work
%TRAINING%software\perl\bin\perl -pi.bak -e 's/_BASE_/%TRAINING%/g' %TRAINING%work\*.pl

我对此有一些问题:

  1. Perl 似乎不喜欢文件名中的通配符
  2. 事实证明,%TRAINING% 将扩展为带有反斜杠的字符串,需要将其转换为正斜杠,并且需要在正则表达式中进行转义。

我该如何解决?

标签: regexperlbatch-file

解决方案


首先,Windows 不使用 shebang 行,所以我不确定你为什么首先要做这些工作。

如果在路径中找到选项,Perl 将读取 shebang 行并查找选项perl,即使在 Windows 上也是如此,但这意味着#!perl如果您想通过 shebang 行传递选项(例如#!perl -n)就足够了。

现在,您可能使用 Cygwin、MSYS 或其他一些 unix 仿真而不是 Windows 来运行程序,但是您在 shebang 行 ( C:...) 中放置了 Windows 路径而不是 unix 路径,所以这也没有任何意义.

尝试存在三个额外的问题:

  1. cmd使用双引号进行引用。
  2. cmd不会像 那样执行通配符扩展sh,所以这取决于你的程序。
  3. 您正在尝试从cmd. 哎哟。

如果我们继续,我们会得到:

"%TRAINING%software\perl\bin\perl" -MFile::DosGlob=glob -pe"BEGIN { @ARGV = map glob, @ARGV; $base = $ENV{TRAINING} =~ s{\\}{/}rg } s/_BASE_/$base/g" -i.bak -- %TRAINING%work\*.pl

如果我们为可读性添加换行符,我们会得到以下内容(cmd不接受):

"%TRAINING%software\perl\bin\perl"
   -MFile::DosGlob=glob
   -pe"
      BEGIN {
         @ARGV = map glob, @ARGV;
         $base = $ENV{TRAINING} =~ s{\\}{/}rg
      }
      s/_BASE_/$base/g
   "
   -i.bak -- %TRAINING%work\*.pl

推荐阅读