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

Hello, One last question for the day and I'll leave you alone...promice :) When writing to a flat data file what adjustments, to the following code, would be needed to skip the first line? Any help would be greatly appreciated.
my @temp; open(DATAFILEIN, "$catagory.dat") || print "Your listing is the fi +rst in this category!<br>"; flock (DATAFILEIN, 2); while(<DATAFILEIN>) { @line_pair = split(/\|/,$_); $time2 = $line_pair[6]; $currenttime = time (); $difference = $currenttime - $time2; #computing the number of seconds before it expires $expires = $expire_after_days * 86400; if($difference < $expires){ push (@temp,$_); } } flock (DATAFILEIN, 8); if (open(DATAFILEOUT, ">$catagory.dat") ) { flock (DATAFILEOUT, 2); print DATAFILEOUT "$company_name|$time|$email|$member1|$member +1phone|$data|$expiretime|$pictureurl|$password|$website|$member2|$mem +ber2phone|$address|$citystatezip|$fax|$catlisting\n"; print DATAFILEOUT @temp; userlog(); if ($emailme eq "yes") { $toemail = $myemail; $fromemail = $email; emailme(); } if ($emailuser eq "yes") { $toemail = $email; $fromemail = $myemail; emailme(); } flock (DATAFILEOUT, 8);

Replies are listed 'Best First'.
Re: Skip a line
by kabel (Chaplain) on Nov 11, 2002 at 18:29 UTC
    just do a read in void context:
    <DATAFILEIN>;
    or use a scalar as a flag.
Re: Skip a line
by jdporter (Paladin) on Nov 11, 2002 at 22:14 UTC
    I'm guessing that you're wanting to have a single line at the top of the file that doesn't change with the rest of them. Some kind of header line, perhaps. In this case, just calling     <DATAFILEIN>; to read in and discard the first line, as others have suggested, would work.

    By the way, I'd write your code (above) as follows:

    my $now = time; my $expire_after_seconds = $expire_after_days * 24 * 60 * 60; open DATAFILEIN, "< $catagory.dat" or die "Your listing is the fir +st in this category!<br>"; flock DATAFILEIN, 2; my @temp = grep { ($now - (split /\|/)[6]) < $expire_after_seconds + } <DATAFILEIN>; close DATAFILEIN; unshift @temp, join( '|', $company_name, $time, $email, $member1, $member1phone, $data, $expiretime, $pictureurl, $password, $website, $member2, $member2phone, $address, $citystatezip, $fax, $catlisting )."\n"; if ( open DATAFILEOUT, "> $catagory.dat" ) { flock DATAFILEOUT, 2; print DATAFILEOUT @temp; close DATAFILEOUT; }
    One thing needs to be stressed: you must explicitly close the file when you're done reading or writing it. Just releasing the lock (calling  flock 8) is not enough. In fact, closing the file also releases the lock, so you don't need to call  flock 8 at all, normally.

    A couple other comments:

    1. You probably will find it more convenient, in the long term, to use a hash variable, rather than that long slew of separate variables. I.e. instead of   print DATAFILEOUT "$company_name|$time|$email|$member1|$member1phone|$data|$expiretime|$pictureurl|$password|$website|$member2|$member2phone|$address|$citystatezip|$fax|$catlisting\n"; you could have

    print DATAFILEOUT join( '|', @userinfo{qw( company_name time email member1 member1phone data expiretime pictureurl password website member2 member2phone address citystatezip fax catlisting )}, "\n";
    for example.

    2. Your emailme() subroutine should probably take arguments, rather than using global variables ($toemail, $fromemail). Then you could it as

    $emailme eq 'yes' and emailme( $myemail, $userinfo{'email'} ); $emailuser eq 'yes' and emailme( $userinfo{'email'}, $myemail );
    Hope this helps,

    jdporter
    ...porque es dificil estar guapo y blanco.

Re: Skip a line
by FamousLongAgo (Friar) on Nov 11, 2002 at 18:36 UTC
    A couple of points on style ( since the answer is already provided ):
    1. use strict

    2. You seem to be setting $toemail and $fromemail as global variables - you should consider scoping them as lexicals, and passing them explicitly to the function: emailme( $fromemail, $toemail ). This will make your code much easier to debug.

    3. Consider using join in your print statement:
      print DATAFILEOUT ( join '|', $company_name, $time, ... ); This also helps avoid typos, and lets you add and remove parameters more easily.
Re: Skip a line
by Enlil (Parson) on Nov 11, 2002 at 18:36 UTC
    If what is meant by the first line is this
    print DATAFILEOUT "$company_name|$time|$email|$member1|$member1phone +|$data|$expiretime|$pictureurl|$password|$website|$member2|$member2ph +one|$address|$citystatezip|$fax|$catlisting\n";
    you can just comment out the line. If on the other hand the first line is the first variable in the array @temp (aka $temp[0]). Then you can always just skip it using a for loop as follows.

    Instead of

    print DATAFILEOUT @temp;

    try something like:

    for (1 .. $#temp) { print DATAFILEOUT $temp[$_]; }
    or the more readable

    my $temp_length = @temp; for my $current_array_index ( 1 .. ($temp_length - 1) ){ print DATAFILEOUT $temp[$current_array_index]; }

    -enlil

      for (1 .. $#temp) { print DATAFILEOUT $temp[$_]; }
      or the more readable
      my $temp_length = @temp; for my $current_array_index ( 1 .. ($temp_length - 1) ){ print DATAFILEOUT $temp[$current_array_index]; }

      What in the world would make you think that second example is more readable than the first?

      Not that I would go to all that trouble anyway...

      print DATAFILEOUT @temp[1..$#temp];
      Now, that's readable! ;-)

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Skip a line
by tachyon (Chancellor) on Nov 11, 2002 at 18:36 UTC

    Presuming you mean *write* you can't skip lines per se. When you open a file with > it overwrites any existing data. When you open a file using >> it appends to the end of the file. These are your choices. If you want to 'skip' the first line, presumably to save it, you will need to read it in, save it, open the file for overwrite, write out the saved first line, then write out the rest of the data.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Hello, When making the change from opening a file by > to >>, I am finding that when adding info to the file all data lines are being copied and rewritten. So I end up with multiple entries of same line being written every time an addition is made. Any way around this?

        >> appends or in other words ADDS TO THE END OF the existing file. All the data lines are not being copied, they are simply being left there and new data added to the end. Here is a guide for you:

        my $file = '/foo/file.txt'; open IN, $file or die "Can't read $file perl says $!\n"; my @lines = <IN>; close IN; for my $line (@lines) { # do stuff with the lines } # rewrite the file in its entirity open OUT, '>$file' or die "Can't write $file perl says $!\n"; print OUT $line[0]; # print out the first line from the old fil +e print OUT @other_stuff; # print whatever else you want close OUT;

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print