我遇到了一个最糟糕的时间。我最近问过Perl Regular Expression for extracting multi-line LaTeX chapter name,并按照建议使用Perl正则表达式测试器,直到我对我的正则表达式感到满意为止。我提交了我的代码并很高兴。
但现在,当我运行程序时:
#!/usr/bin/perl -i.old # In-place edit, backup as '.old'
use strict;
use warnings;
use Path::Tiny;
my $filename = shift or die "Usage: $0 FILENAME";
my $content = path($filename)->slurp_utf8;
$content =~ s/chapter/addchap/g;
path($filename)->spew_utf8($content);
我最终得到一个空文件。这很奇怪 - 这个替换的变体(如s/\\chapter/\\addchap/g;
)因空文件而失败,但不同的替换,如$content =~ s/ //g;
则不然。更奇怪的是,perl -i
旗帜也没有受到尊重。到底是怎么回事?
以下是一些示例输入:
\chapter{\texorpdfstring{{I} {Into the
Primitive}}{I Into the Primitive}}
Buck did not read the newspapers, or he would have known that trouble
was brewing, not alone for himself,
我根据答案更新了我的代码,但我仍然得到空文件。
#!/usr/bin/perl
use strict;
use warnings;
use Path::Tiny;
my $filename = shift or die "Usage: $0 FILENAME";
my $content = path($filename)->slurp_utf8;
$content =~ s/\\chapter/\\addchap/gs;
path($filename)->spew_utf8($content);
我发现真正令人困惑的是,有些替换“有效”,例如:
$content =~ s/the/thee/g;
但即便
$content =~ s/ch//g;
以空文件失败。
答案 0 :(得分:3)
你不希望同时拥有-i
旗帜和Path :: Tiny。 -i
正在将perl置于一种模式,即尝试打开并替换 你的文件。它与打开文件并自行重写不兼容。
一个选项就是删除-i
标志;你的代码应该按原样运行(但它不会产生备份文件,并且文件替换不会是原子的)。
另一种方法是保留-i
标志,但用
use open ':encoding(UTF-8)';
while (<>) {
s/chapter/addchap/g;
print;
}
(消除所有Path :: Tiny的东西)。 Perl将隐式添加其余部分。
这相当于单行
perl -CSD -i.old -pe 's/chapter/addchap/g' somefile
答案 1 :(得分:1)
脚本第一行的-i
command line option可能会导致此问题。尝试删除它。
当使用perl -i
调用时,Perl会在脚本周围包含一些代码,以循环遍历命令行上命名的每个文件;依次将每一行读入$_
;调用你的脚本(每行一次);收集脚本打印到STDOUT的输出并将其写入临时文件;然后在最后一行之后,将临时文件重命名为原始文件的顶部。这称为“就地编辑”。
这对于1行来说特别方便,因为您不需要编写样板代码来读取文件中的输入并将输出写入文件 - 您只需编写处理代码即可。在您的情况下,您已经编写了该样板(使用Path :: Tiny),因此Perl的-i
实现和您的脚本正在读取输入文件并编写输出文件。由于您的脚本没有向STDOUT输出任何内容,-i
将最终生成一个空文件。