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

Hi Monks,

Title may be a bit misleading. I know how to read the last line of the file, but what I want to know is the best method to detect it. I have a simple text file with a bunch of e-mail addresses:
blah@blah.com blah@somedomain.com blah@johndoe.com
Now I want to read this file and print it out so I can copy and paste to my e-mail program (outlook) and send them a announement. So I want to print the content of this textfile into a textarea to copy and paste.

Heres my code that reads the file, and prints line by line into the textarea.
my $file = "emails.txt"; open(FILE, $file) or die "cannot open $file : $!\n"; @content = reverse (<FILE>); close FILE; print "<textarea cols=\"75\" rows=\"22\">"; foreach $address (@content) { chomp($address); print "$address, "; } print "</textarea>";
Now heres my problem, the above code prints this into the textarea:
blah@johndoe, blah@somedomain.com, blah@blah.com,
Notice the comma at end (blah@blah.com,), how can I detect the end of the line of this file so I can tell Perl not to print the last "," ? So basically I want the contents of textarea to look like thisblah@johndoe, blah@somedomain.com, blah@blah.com

I'm building this as a add-on to a newsletter script so my friend (whose not really good with computers) can goto this script and copy the e-mails from the textarea box and paste it directly into her Outlook address. I really would like to learn this and give her extra convenience by not having her delete the last trailing "," manually.

Thanks Monks

Replies are listed 'Best First'.
Re: Detecting Last line of a file
by gam3 (Curate) on Jun 18, 2005 at 11:19 UTC
    Use join:
    ...
    chomp @content; print join(', ', @content);
    ...

    -- gam3
    A picture is worth a thousand words, but takes 200K.
Re: Detecting Last line of a file
by davidrw (Prior) on Jun 18, 2005 at 13:26 UTC
    The join method is definitely the way to go in this case, but to answer more generally (there was a recent node about this: Don't print on the last loop , but i can't find it at the moment Update Thanks omega_monk!), if you just flip the thought process and prepend commas instead of append them, it becomes:
    my $addrCt = 0; foreach $address (@content) { print ", " if $addrCt++; # won't be done the first time chomp($address); print $address; }
      I believe the node that you are referring to is 466164.

      Rather than keeping an extra variable around just test $address:

      print ", " if $address; # won't be done the first time

      Perl is Huffman encoded by design.
        Why wouldn't it be done the first time? That doesn't work unless $content[0] is somehow false .. since we're looping through @content and they're presumably all non-false, then $address is always set. Best way to get rid of the temp var is to just use split, or dpending on context (i.e. if you're reading a file) you could do print "," if $. > 1;.
Re: Detecting Last line of a file
by data64 (Chaplain) on Jun 18, 2005 at 14:46 UTC

    To detect last line of file, use the "eof" function. Check perlfunc for more informtion about eof

      Yeah, this EOF seems like a good way to go. It's addressed in some, but not all (eg, not the activestate) perlfaq5:

      "How do I change one line in a file/delete a line in a file/insert a line in the middle of a file/append to the beginning of a file?

      .....

      The following code snippet deletes the last line of a file without making a copy or reading the whole file into memory:

      open (FH, "+< $file"); while ( <FH> ) { $addr = tell(FH) unless eof(FH) } truncate(FH, $addr);"
      Presumably you can modify this to do things other than deleting. Hope this helps!

      Or, you could do like the most recent perlfaq5 suggests and use Tie::File:

      "How do I change one line in a file/delete a line in a file/insert a line in the middle of a file/append to the beginning of a file? Use the Tie::File module, which is included in the standard distribution since Perl 5.8.0."

Re: Detecting Last line of a file
by chas (Priest) on Jun 18, 2005 at 12:21 UTC
    Or perhaps (after chomping if necessary)
    print shift @content; for(@content){print ", $_";}

    chas
Re: Detecting Last line of a file
by g0n (Priest) on Jun 18, 2005 at 10:49 UTC
    This might not be the best way, but it should work:

    Update: It isn't the best way, isn't even a good way. See later in the thread for better solutions. Doh!

    my $file = "emails.txt"; open(FILE, $file) or die "cannot open $file : $!\n"; @content = reverse (<FILE>); close FILE; print "<textarea cols=\"75\" rows=\"22\">"; foreach $address (@content) { chomp($address); print $address; if ($address ne $content[-1]){print ", "} } print "</textarea>";

    (In other words, print the comma unless its the last line). That assumes that each element in @content is unique. Given that you are using them for a mailing list, that should be a valid assumption. If not:

    .. my $counter=0; foreach $address (@content) { chomp($address); print $address; $counter++; if ($counter < @content){print ", "} } ..

    Set a counter and print the comma if the counter is smaller than the number of elements in the array.

    --------------------------------------------------------------

    g0n, backpropagated monk