使用来自powershell的perl编辑文件

时间:2012-06-04 19:01:22

标签: perl powershell

我在目录中有一个文件列表files.txt。我想在每个文件中运行文本替换。

$f = (get-content files.txt)
Foreach ($i in $f) { perl -pi -we "s/(\d{0,4})- /$1 - /g" $i }

但是如果没有备份,perl不喜欢这样做。

  

没有备份就无法进行就地编辑。

所以我将.bak添加到-i:

$f = (get-content files.txt)
Foreach ($i in $f) { perl -pi.bak -we "s/(\d{0,4})- /$1 - /g" $i }

现在它抱怨道:

  

无法打开perl脚本“.bak”:没有这样的文件或目录

我错过了什么?

更新:

我更喜欢的是一种完全没有shell的方法。我可以用per $^I以某种方式在perl中执行此循环吗?

2 个答案:

答案 0 :(得分:1)

my $qfn = 'files.txt';
open(my $fh, '<', $qfn)
   or die("Can't open file list \"$qfn\": $!\n");

local @ARGV = <$fh>;
local $^I = '.bak';
local $_;
while (<>) {
   s/(\d{0,4})- /$1 - /g;
   print;
}

当/ a未使用时,

\d匹配超过0-9,因此您可能需要

 s/(\d{0,4})- /$1 - /ag;
   -or-
 s/([0-9]{0,4})- /$1 - /g;

请注意,上述内容并不能阻止您想要匹配5位数字。为此,请使用:

 s/(?<![0-9])([0-9]{0,4})- /$1 - /g;

现在,当您了解\K时,没有理由将数字替换为自己。

 s/(?<![0-9])[0-9]{0,4}\K- / - /g;

最后,我们也可以摆脱重复的-

 s/(?<![0-9])[0-9]{0,4}\K(?=- )/ /g;

答案 1 :(得分:1)

池上绝对是正确的。在powershell中,-i.bak被解释为-i .bak。解决方案是强制powershell将其作为单个参数传递。

像     perl'-pi.bak'-we ....#用单引号括起来。