Perl脚本可以';不要使用Tie::文件

Perl脚本可以';不要使用Tie::文件,perl,unix,Perl,Unix,我正在尝试运行一个使用Tie::File模块的perl脚本 它基本上应该做的是读取当前目录中的所有文件,切断第一个文档的最后一行,然后切断其他每个文档的第一行和最后一行以及最后一个文档的第一行,然后将所有内容写入新文档 当我试图运行我的脚本时(其中可能有一些错误…如果您发现任何错误,如果有人能够纠正,我将非常高兴),我收到一条错误消息: Can't locate object method "TIEARRAY" via package "TIE:File" at script.pl line 2

我正在尝试运行一个使用Tie::File模块的perl脚本

它基本上应该做的是读取当前目录中的所有文件,切断第一个文档的最后一行,然后切断其他每个文档的第一行和最后一行以及最后一个文档的第一行,然后将所有内容写入新文档

当我试图运行我的脚本时(其中可能有一些错误…如果您发现任何错误,如果有人能够纠正,我将非常高兴),我收到一条错误消息:

Can't locate object method "TIEARRAY" via package "TIE:File" at script.pl line 28, <$fh> line 7.

如果所有东西都安装好了,我从终端收到的Tie::Array是最新的(v1.06),Tie::File是最新的(v1.00),因此它们必须正确安装

#!/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;
#/usr/bin/perl
使用化学武器;
使用Tie::文件;
使用Tie::数组;
my$cwd=getcwd();
我的$buff='';
#获取cwd中的所有文件。
#my@files=grep{-f&/\.txt$/}readdir$cwd;
my@files=grep(-f,);
#切断第一个(文件[0])文件的页脚
打印“开始”$文件[0]。“\n”;
使用Tie::文件;
tie(@lines,tie::File,$files[0])或die“无法更新$File:$!”;
删除$行[-1];
#将$files[1]的页眉和页脚剪切到$files[-2]
对于($a=1,$a<$#files-1,$a++){
打印“正在打开”。$文件。“\n”;
使用Tie::文件;
tie(@lines,tie::File,$files[$a])或die“无法更新$File:$!”;####这是第28行
删除$行[0];
删除$行[-1];
打开(文件“”$allfilename或die$!;
#将缓冲区写入输出文件。
打印$outputfile$buff;
关闭$outputfile;

Perl模块名称区分大小写。该模块称为Tie::File,而不是Tie::File或Tie::File。

坦率地说,您的程序有点混乱。您似乎在尝试一些事情,希望它们能工作,但没有任何真正的推理

我已经重构了你的代码来做我认为你想要做的事情

  • 您必须始终将
    use strict
    use warnings
    添加到您编写的每个Perl程序中,并使用
    my
    声明所有变量,使其尽可能接近它们的第一个使用点。仅凭这些简单的措施就可以避免许多简单错误,否则您将忽略这些错误

  • 您不需要
    Tie::Array
    Cwd
    。它们与此程序无关

  • 您的
    tie
    语句需要一个字符串作为第二个参数,因此您需要使用
    'tie::File'
    而不是
    tie::File

  • 您的输出文件
    Trace.txt
    将由
    glob找到,因此除非您采取措施明确排除它,否则您的程序将复制修剪第一行和最后一行,并将该文件的内容复制到自身。在我的程序中,我只需在
    for
    循环中检查当前文件名是否为
    Tra如果是,则跳过它

  • 在缓冲区中积累数据毫无意义。您也可以在遇到数据时将其写入文件

  • 绑定数组
    @lines
    中的行没有尾随的换行符,因此您可能希望在写入文件时添加一行

  • 正如评论中所讨论的,您正在使用
    Tie::FILE
    Tie::FILE
    以及正确的
    Tie::FILE
    。并且您已经编写了
    use Tie::FILE
    (及其变体)总共四次。当然这不会阻止程序工作,但这是模糊思维的主要表现,你只是希望他们让你的程序工作的陈述

  • 在数组的最后一个元素以外的任何元素上使用
    delete
    ,只会将该元素设置为
    unde
    :它不会删除它,绑定文件中发生的所有事情就是删除文本,只留下一个换行。您需要使用

  • 将文件分为第一行、最后一行和其他行是不必要的,这会使代码难以辨认。在下面的程序中,我使用了一个循环,删除文件的第一行,除非它是第一个文件,并删除文件的最后一行,除非它是最后一个文件。这样更容易阅读

  • 最后,我不确定您是否要从现有文件中删除第一行和最后一行,或者您是否只想将所有数据复制到输出文件中,除了这些行。我已经根据您的规范编写了我的程序,但请记住,每次运行该程序时,文件都会缩短两行,这可能是错误的y不是你想要的效果。如果你有不同的需求,并且看不到如何修改代码来实现它,那么请问另一个问题

我希望这对你有帮助

use strict;
use warnings;

use Tie::File;

my @files = grep -f, glob '*.txt';

my $all_filename = 'Trace.txt';
open my $out_fh, '>', $all_filename or die qq{Unable to open "$all_filename" for output: $!};

for my $i ( 0 .. $#files ) {

  my $file = $files[$i];
  next if $file eq $all_filename;

  print "Opening $file\n";

  tie my @lines, 'Tie::File', $file or die qq{Can't update "$file": $!};
  splice @lines,  0, 1 unless $i == 0;
  splice @lines, -1, 1 unless $i == $#files;

  print $out_fh "$_\n" for @lines;
}

close $out_fh;

你只需要“使用Tie::File”一次。文件和文件也不一样。Tie和Tie也不一样。多次使用Tie::File没有什么坏处,但我还是删除了它……问题也不在文件中,而在Tie::File中,它应该是Tie::File…@Buitenlander:我修改了这个解决方案,以回应你在稍后的评论(!)问题是它没有输出任何内容。我犯了一个错误,在将输入内容复制到输出文件之前,使用
unte@lines
关闭并更新每个输入。我只是简单地删除了
unte
,因为当
@lines
在循环结束时超出范围时,它会自动发生。Howev呃,这对你没有多大用处,因为正如我所怀疑的那样,你不希望修改输入文件。但是,对于其他使用该解决方案的人来说,这是很好的。
#!/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;
use strict;
use warnings;

use Tie::File;

my @files = grep -f, glob '*.txt';

my $all_filename = 'Trace.txt';
open my $out_fh, '>', $all_filename or die qq{Unable to open "$all_filename" for output: $!};

for my $i ( 0 .. $#files ) {

  my $file = $files[$i];
  next if $file eq $all_filename;

  print "Opening $file\n";

  tie my @lines, 'Tie::File', $file or die qq{Can't update "$file": $!};
  splice @lines,  0, 1 unless $i == 0;
  splice @lines, -1, 1 unless $i == $#files;

  print $out_fh "$_\n" for @lines;
}

close $out_fh;