我正在尝试运行一个使用Tie :: File模块的perl脚本。
它基本上应该做的是读取当前目录中的所有文件,切掉第一个文档的最后一行,然后是每个其他文档的第一行和最后一行以及最后一个文档的第一行,然后将所有内容写入新文档。
当我试图运行我的脚本时(可能会有一些错误...如果有人能找到错误,我会很高兴)我收到错误消息:
Can't locate object method "TIEARRAY" via package "TIE:File" at script.pl line 28, <$fh> line 7.
我在代码中标记了第28行。
我已经安装了最新版本的Tie :: File并使用
进行了检查cpan Tie::File
和
cpan Tie::Array
如果安装了所有内容,我收到的Tie :: Array是最新的(v1.06),Tie :: File是最新的(v1.00)终端,因此必须正确安装。< / p>
#!/usr/bin/perl
use Cwd;
use Tie::File;
use Tie::Array;
my $cwd = getcwd();
my $buff = '';
# Get all files in cwd.
#my @files = grep { -f && /\.txt$/ } readdir $cwd;
my @files = grep ( -f ,<*.txt>);
# Cut off footer of first (files[0]) file
print 'Opening' . $files[0] . "\n";
use Tie::File;
tie (@lines, Tie::File, $files[0]) or die "can't update $file: $!";
delete $lines[-1];
# Cut off header and footer of $files [1] to $files[-2]
for ($a = 1, $a < $#files-1, $a++){
print 'Opening' . $file . "\n";
use Tie::FILE;
tie (@lines, TIE::File, $files[$a]) or die "can't update $file: $!"; ####this is line 28
delete $lines[0];
delete $lines[-1];
open (FILE, "<", $files[$a]) or die $!;
while (my $line =<FILE>) {
$buff .= $line;
}
close FILE;
}
print 'Opening' . $files[-1] . "\n";
use Tie::FILE;
tie (@lines, TIE::File, $files[-1]) or die "can't update $file: $!";
delete $lines[0];
open (lastfile, "<", $files[-1]) or die "can't open $files[-1]: $!";
while (my $line =<lastfile>) {
$buff .= $line;
}
close lastfile;
# Write the buffer to a new file.
my $allfilename = $cwd.'/Trace.txt';
print 'Writing all files into new file: ' . $allfilename . "\n";
open $outputfile, ">".$allfilename or die $!;
# Write the buffer into the output file.
print $outputfile $buff;
close $outputfile;
答案 0 :(得分:5)
Perl模块名称区分大小写。该模块称为Tie :: File,而不是Tie :: FILE或TIE :: File。
答案 1 :(得分:2)
你的程序坦率地说有点混乱。你似乎正在尝试一些事情,希望它们有效,但没有任何真正的推理。
我已经重构了你的代码,以便在下面做我认为你想要的东西。以下是我所做的主要更改
您必须始终将use strict
和use warnings
添加到您编写的每个 Perl程序中,并使用{{声明所有变量1}}尽可能接近他们的第一个使用点。仅这些简单的措施就可以避免您忽略的许多简单错误
您不需要my
或Tie::Array
。它们与此计划无关
您的Cwd
语句需要字符串作为第二个参数,因此您需要使用tie
代替'Tie::File'
您的输出文件Tie::File
将由Trace.txt
glob找到,因此,除非您采取措施明确排除它,否则您的程序将复制第一行和最后一行并修复内容该文件本身。在我的程序中,我只是在<*.txt>
循环中检查当前文件名是否为for
,如果是,则跳过它
在缓冲区Trace.txt
中累积数据毫无意义。您也可以在遇到文件时将数据写入文件
绑定数组$buff
中的行没有尾随换行符,因此您可能希望在写入文件时添加一行
正如评论中所讨论的那样,您使用的是@lines
和Tie::FILE
以及正确的TIE::File
。你总共写了Tie::File
(及其变体)四次。当然它并没有阻止程序的运行,但这是一个模糊思维的主要表现,并且你只是声明,希望它们使你的程序工作
在数组的 last 元素之外的任何内容上使用use Tie::File
只需将该元素设置为delete
:它不会删除它,并且绑定文件中发生的所有事情是删除文本只留下换行符。您需要使用splice
代替
将您的文件分成第一个,最后一个,其余部分是不必要的,并使您的代码难以理解。在我的程序中,我使用了一个循环来删除文件的第一行,除非它是第一个文件,并删除文件的最后一行,除非它是最后一个文件。这样阅读起来容易得多
最后,我完全不确定您是要删除现有文件中的第一行和最后一行,还是只想将所有数据复制到您的输出文件除了这些行。我已根据您的规范编写了我的程序,但请记住,每次运行时,文件都会缩短两行,这可能不是您想要的效果。如果您有不同的要求,并且无法查看如何修改代码以实现它,那么请提出另一个问题。
我希望这会对你有所帮助。
undef