10 lines revisited

T

Todd Anderson

Hello,
Because my host times out a script after 60 seconds, I created a cronjob
that prompts my script every minute. When started it counts the number
of lines in a flat file divides it by 10 to determine how many times it
will take to finish the billing ($number_of_sends). Then each time it's
prompted it processes 10 lines at a time ie: @billingnumber =
(351..360); and deducts the $number_of_sends by 1 for the next prompt.
This all works fine but I can't quite figure out how to get it to
recognize the 10 lines to process. Below is what I have. It is working
but it's also multiplying every line by 10.
Thanks in advance for any help.
(please NO rectal discharge)

$e_number = "0";
open (USERS, "$file") || billerror
("$file Billing Notice" );
flock(USERS, 2);
while (<USERS>)
{
$line = $_;
chomp $line;
@fields = split (/\|/, $line);
$e_number++;
foreach $billingnumber (@billingnumber){
if ($billingnumber eq "$e_number"){

#do a bunch of stuff to these lines

}#e_number
else{ $hold_row .="$line\n"; }
}#@billingnumber
}#while
flock(USERS, 8);
close (USERS);
 
J

James Willmore

Hello,
Because my host times out a script after 60 seconds, I created a cronjob
that prompts my script every minute. When started it counts the number
of lines in a flat file divides it by 10 to determine how many times it
will take to finish the billing ($number_of_sends). Then each time it's
prompted it processes 10 lines at a time ie: @billingnumber =
(351..360); and deducts the $number_of_sends by 1 for the next prompt.
This all works fine but I can't quite figure out how to get it to
recognize the 10 lines to process. Below is what I have. It is working
but it's also multiplying every line by 10.
Thanks in advance for any help.
(please NO rectal discharge)

$e_number = "0";
open (USERS, "$file") || billerror
("$file Billing Notice" );
flock(USERS, 2);
while (<USERS>)
{
$line = $_;
chomp $line;
@fields = split (/\|/, $line);
$e_number++;
foreach $billingnumber (@billingnumber){
if ($billingnumber eq "$e_number"){

#do a bunch of stuff to these lines

}#e_number
else{ $hold_row .="$line\n"; }
}#@billingnumber
}#while
flock(USERS, 8);
close (USERS);

One of the things you may want to think about using is the "$." operator.
It holds the current line number of the file being proccessed. This
mitigates the need to read the whole file into an array when doing the
processing. So, when reading the file you could do something like
(untested):

while(<FILE>){
next unless ($. >= 1);
... do whatever to the current line ....
last if ($. == 10);
}

So, in summary .....

- if the current line is equal to or greater than the line you need, do
something with the file
- process the line if we need to and it matches the lower end of the
criteria
- after you process the line (if required), break out of the while with
the 'last' if we reached the last line we wish to process.

Hope I explained this is such a way as you can understand and you can use
this in your script.

--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
Serocki's Stricture: Marriage is always a bachelor's last
option.
 
T

Tad McClellan

$e_number = "0";


If you intend for it to be a number, then do not force it to be a string.

You should always have "use strict" enabled.


my $e_number = 0;

open (USERS, "$file") || billerror


perldoc -q vars

What's wrong with always quoting "$vars"?

flock(USERS, 2);


You should import the constants, they can be different on
different platforms.

You should check the return value to see if you actually
got what you asked for.

while (<USERS>)
{
$line = $_;


If you want it in $line, then put it into $line straightaway:

chomp $line;
if ($billingnumber eq "$e_number"){


What's wrong with always quoting "$vars"?

You are using the wrong operator.

eq is for testing strings.

== is for testing numbers.

else{ $hold_row .="$line\n"; }


Why chomp() the newline off only to put it back in again/

flock(USERS, 8);


You should never unlock the file.

You have created a race here...

close (USERS);


close() will release the lock for you.
 
A

A. Sinan Unur

(please NO rectal discharge)

What is it about "a minimal self contained example others can compile and
run" that is so hard to understand?

In the absence of relevant information to solving whatever your problem
is, here is an untested script which you can call with:

../showlines.pl filename 5 10

to show lines 5 to 10 in a file called filename:

#! /usr/bin/perl

use strict;
use warnings;

use Fcntl qw:)seek :flock);

my ($fn, $start, $end) = @ARGV;
if( $start > $end) { ($start, $end) = ($end, $start); }

open my $FILE, '<', $fn or die "Cannot open $fn: $!";

flock $FILE, LOCK_SH;
seek $FILE, 0, SEEK_SET
or die "Cannot seek to beginning of $FILE: $!";

while( $. < $start - 1 ) { <$FILE>; }
while( $. < $end ) { print $., ': ', scalar <$FILE>; }

flock $FILE, LOCK_UN;

__END__
 
T

Tad McClellan

James Willmore said:
On Wed, 21 Jan 2004 12:57:19 -0700, Todd Anderson wrote:


One of the things you may want to think about using is the "$." operator.


If this is the same "Todd Anderson", then he heard that
already 3 years ago...


Message-Id: <[email protected]>
 
B

Ben Morrow

use strict;
use warnings;

use Fcntl qw/:flock/;
$e_number = "0";

my $e_number;

If you must initialise it, initialise it to 0 rather than "0"; but
undef is just fine.
open (USERS, "$file") || billerror
("$file Billing Notice" );

open (my $USERS, $file) || billerror(...);

or, preferably

open my $USERS, $file or billerror(...);

I presume billerror() includes $! in its output?
flock(USERS, 2);

flock(USERS, LOCK_EX) or billerror("can't lock $file");
while (<USERS>)
{
$line = $_;

Why? What's wrong with $_?
chomp $line;
@fields = split (/\|/, $line);

my ...;
$e_number++;

As someone else said, use $.; alternatively, I would use Tie::File.
foreach $billingnumber (@billingnumber){

foreach my $billingnumber (@billingnumber) {
if ($billingnumber eq "$e_number"){

You certainly don't need the ""; and you probably meant to write

if ($billingnumber == $e_number) {
#do a bunch of stuff to these lines

}#e_number
else{ $hold_row .="$line\n"; }
}#@billingnumber
}#while
flock(USERS, 8);

An explicit call to flock(..., LOCK_UN) is almost always a bug. The
lock will be released when the handle is closed.
close (USERS);

If you use open my $USERS, ... above you don't need to call close: the
handle will be closed when it goes out of scope.

Ben
 
J

James Willmore

If this is the same "Todd Anderson", then he heard that
already 3 years ago...


Message-Id: <[email protected]>

Ah .... that explains the final comment he made.

--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
Tact is the ability to tell a man he has an open mind when he has
a hole in his head.
 
T

Tad McClellan

Anno Siegel said:
Todd Anderson said:

[question snipped]
Thanks in advance for any help.
(please NO rectal discharge)

That's a rude thing to say when you are asking strangers for help, don't
you think?


It was like a little sign on his post:

I've been flamed here before. Don't do it again.


In other words: do it my way, don't do it your long-established way.

Pffft!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top