[Solved] Perl Script can’t use Tie::File


Your program is frankly a bit of a mess. You seem to be trying things in the hope that they work but without any real reasoning.

I have refactored your code to do what I think you want below. Here are the main changes I have made

  • You must always add use strict and use warnings to every Perl program you write, and declare all your variables with my as close as possible to their first point of use. Those simple measures alone will save you from a lot of simple errors that you will otherwise overlook

  • You don’t need Tie::Array or Cwd. They are irrelevant to this program

  • Your tie statement needs a string as the second parameter, so you need to use 'Tie::File' instead of Tie::File

  • Your output file Trace.txt will be found by the <*.txt> glob, so unless you take measures to specifically exclude it your program will copy trim the first and last lines and copy the contents of that file to itself. In my program I have simply checked in the for loop whether the current file name is Trace.txt and skipped it if so

  • There is no point in accumulating the data in a buffer $buff. You may as well just write the data to the file as you encounter it

  • The lines in the tied array @lines have no trailing newline, so you will presumably want to add one when you write to the file

  • As has been discussed in the comments, you are using Tie::FILE and TIE::File as well as the correct Tie::File. And you have written use Tie::File (and its variations) four times in total. Sure it doesn’t stop the program from working, but it is a major indication of foggy thinking, and that you are just statements around in the hope that they make your program work

  • Using delete on anything other than the last element of an array just sets that element to undef: it doesn’t delete it, and all that happens in the tied file is that the text is removed leaving just a newline. You need to use splice instead

  • Separating your files into the first, the last, and the rest is unnecessary and makes your code illegible. In my program below I have used a single loop that removes the first line of the file unless it’s the first fil, and removes the last line of the file unless it’s the last file. It’s far easier to read that way

  • Lastly, I’m not at all sure that you want to remove the first and last lines from the existing files, or if you just want all the data copied to your output file except those lines. I have written my program according to your specification, but bear in mind that the files will get shorter by two lines every time you run it, and that probably isn’t the effect you want. If you have a different requirement and can’t see how to modify the code to achieve it then please ask another question.

I hope this helps you.

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;

1

solved Perl Script can’t use Tie::File