kevinw has asked for the wisdom of the Perl Monks concerning the following question:

sorry to modify my original question, but this is what i'm trying to do....i have a file $infile in the following format:
date data1 200205 5.3 200206 3.2 200207 4.3 200208 5.3
what i want to do is look at the last line and compare the date (in this case 200208) and if it is equal to $date, print and replace the last line with $newline. Sorry if it's confusing. Thanks in advance

Replies are listed 'Best First'.
Replace Last Line in File
by kevinw (Novice) on Aug 07, 2002 at 14:19 UTC
    Any ideas on what is the best way to print and replace the last line of a file?

    Edit by tye: This was originally a near-duplicate root node

      perl -pi -we '($_,$@)=($@,$_);$_.="New line\n"if eof' your_file
      Abigail
        Why not <code>perl -pi -we '$_="New line\n"if eof' your_file<code>

      This prints the last line before it has been changed:     perl -i -pe '$last = $_; s/foo/bar/ if eof; END{print $last}' file

      And this changes the last line and then prints it:     perl -i -ne 's/foo/bar/ if eof; print $last = $_; END{print $last}' file

      --
      John.

      perldoc -q change line file perl 5.008 will tell you to use Tie::File, older perls offer other examples.

      ~Particle *accelerates*

Re: search and replace last line
by waswas-fng (Curate) on Aug 07, 2002 at 15:50 UTC
    Depends if the file is small enough to fit into memory, if it is here ya go..

    -Waswas
    #!/usr/local/bin/perl my @fileslurp = (); my $datefld = ""; my $testdate = "200208"; my $newline = "Not the old date\n"; my $thisfile = "/var/tmp/junk.log"; open (FILE,"$thisfile"); @fileslurp = <FILE>; close FILE; ($datefld) = split(/ /,@fileslurp[$#fileslurp]); @fileslurp[$#fileslurp] = $newline if ($datefld eq "$testdate") ; foreach $x (@fileslurp) { print $x; }
      thanks....what is the easiest way to replace the last line of the file?
        If you don't want to do the traditional approach of buffering and re-writing the data yourself, you can try Tie::File. A small example using your test data:

        #!/usr/bin/perl -wd use Tie::File; tie @array, 'Tie::File', "test.txt" or die "cannot tie file\n"; ($date,$data) = split( /\s+/, $array[-1] ); $data = "whatever" if $date eq "200208"; $array[-1] = "$date $data"; untie @array;

        -derby

Re: search and replace last line
by abitkin (Monk) on Aug 07, 2002 at 15:41 UTC
    Why don't you use tail to get the last line, compair that, then if you need to alter it (I recomend using nl to get the number of lines) use head with the number of lines - 1 plus your line.

    eg.
    perl addline.pl -f test.dat
    # Get the file through get opt my $line = `nl $file | tail -n 1`; my @items = ($line =~ /^\s*([0-9]+)\s+([0-9]+)\s+/); my $lineNum = int($items[0]) - 1; my $newDate = $items[1]; my $fileTmp = $file . ".tmp"; if($date eq $newDate){ system("head -n $lineNum $file > $fileTmp"); system("echo $newline >> $fileTmp"); system("rm $file;mv $fileTmp $file"); }


    I haven't compiled this, but you should have an idea of how this works.

    ps. if you're doing this on windows, download cygwin and use the nl, tail, and head that they have in their packages. (They are exes, and will work with system.)
Re: search and replace last line
by kschwab (Vicar) on Aug 09, 2002 at 14:01 UTC
    If this file can get large, you may get some benefit out of not rewriting the whole file.
    #!/usr/bin/perl my $file=shift(@ARGV); open(FILE,"+<$file") or die; while (<FILE>) { if (eof(FILE)) { seek(FILE,-(length($_)),2) or die("$!\n"); print FILE "replacement string\n"; last; } } close FILE;
    Note that you don't really have to read the whole file either. You could seek() to the end and then back up looking for a newline. Or, if each line is the same length ( it appears that they may be...), you can just go the end and back up X bytes.