2

我在一个目录中有一个文件 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”:没有这样的文件或目录

我错过了什么?

更新:

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

4

2 回答 2

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;
}

\d不使用 /a 时匹配超过 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;
于 2012-06-04T22:34:41.163 回答
1

ikegami 完全正确。在 powershell -i.bak 被解释为 -i .bak。解决方案是强制 powershell 将其作为单个参数传递。

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

于 2012-08-08T09:55:27.890 回答