我想用不同调用的同一文件的副本填充文件夹。我使用Windows filelist.txt
创建了cmd
以获取文件名,然后使用以下代码:
use strict; # safety net
use warnings; # safety net
use File::NCopy qw(copy);
open FILE, 'C:\blabla\filelist.txt';
my @filelist = <FILE>;
my $filelistnumber = @filelist + 1;
my $file = 0;
## my $filename = 'null.txt';
my $filename = $filelist[$file];
while( $file < $filelistnumber ){
copy('base.smp','temp.smp');
rename 'temp.smp', $filename;
$file = $file + 1;
};
如果我尝试将其重命名为'test.smp'或其他什么,它就可以了。如果我尝试上面的代码,我会得到这个:
Use of uninitialized value $filename in print at blablabla/bla/bla.pl line 25, <FILE> line 90.
我做错了什么?我觉得有一些小错误,可能是语法错误,一直在躲避我。
答案 0 :(得分:3)
首先,这里有一些改进的代码:
use strict;
use warnings;
use File::Copy;
while (<>) {
chomp;
copy('base.smp', $_) or die $!;
}
您将其保存为script.pl
并按如下方式调用它:
$ perl script.pl C:\blabla\filelist.txt
这段代码在哪些方面有所改进?
<>
)隐式迭代作为命令行参数给出的文件,这样简单而优雅。copy()
由于某种原因失败的情况下处理错误。while
循环或C风格的for
循环来迭代数组,这些数组都容易出现一个错误而忘记重新分配正如你所发现的那样,迭代器。open()
的旧2参数语法。 (嗯,不明确,但这超出了这个答案的范围。)我做错了什么?我觉得有一些小错误,一个 可能是语法错误,这一直在躲避我。
语法错误会导致出现错误消息,指出存在语法错误。但既然你问你做错了什么,那就让我们来看看吧:
use File::NCopy qw(copy);
此模块最后一次更新于2007年,并标记为已弃用。不要使用它。
open FILE, 'C:\blabla\filelist.txt';
您应该使用open的三参数形式,使用词法文件句柄,并始终检查系统调用的返回值。
my @filelist = <FILE>;
您很少需要将整个文件粘贴到内存中。在这种情况下,你没有。
my $filelistnumber = @filelist + 1;
这条线没有任何内在错误,但是当你考虑以后如何使用它时。请记住,数组是0索引的,因此您只需设置一个超出范围的数组索引。但我们会在一秒钟之内完成。
my $filename = $filelist[$file];
您通常希望在循环中执行此分配,以免在递增计数器后忘记更新它(这正是此处发生的事情)。
while( $file < $filelistnumber ){
这是在Perl中迭代数组的奇怪方法。您可以使用典型的C-style for
loop,但最常用的是使用foreach
-style loop:
for my $element (@array) {
...
}
列表的每个元素都本地化为循环,您不必担心计数器,条件或数组边界。
copy('base.smp','temp.smp');
同样,请务必检查系统调用的返回值。
rename 'temp.smp', $filename;
无需copy
和 rename
。您可以第一次复制到最终目标文件名。但是如果 要重命名,请始终检查系统调用的返回值。
};
块不需要像simple statements这样的分号终止。
答案 1 :(得分:0)
您应该避免使用裸字文件句柄。打开时,您应该使用类似的文件引用打开,并确保在失败时捕获它:
open(my $fh, '<', 'C:\blabla\filelist.txt') or die "Cannot open filelist.txt: $!";
$ fh变量将包含您的文件引用。
对于您的问题,看起来您的filelist.txt必须为空。尝试使用Data :: Dumper打印出@filelist以确定它的内容。
use Data::Dumper;
编辑:
看起来您还希望将$ filename变量设置为列表中的每个迭代的下一个变量,因此将$filename = $filelist[$file];
放在循环的开头。
你的问题可能是你循环太远了?尝试删除+ 1
my $filelistnumber = @filelist + 1;