Find and delete a line, problems finding

S

sakuragirl1

I got my first PERL project last Monday and have written 3 pages of
working PERL, but 1 page is driving me nuts! I am very much a newbie,
so please have patience with me. below is a snippet of my code that is
having problems.

open(LISTFILE, "<.ccglist");
open(TEMPFILE, ">.tempfile");

while ($line=<LISTFILE>) {
print TEMPFILE $line unless $line =~ (/$accountnumber/ &&
/$effectivedate/);
}

close TEMPFILE; close LISTFILE;
unlink ".ccglist";
rename ".tempfile", ".ccglist";

I have finally got the deleting of a line working, but it is the
finding i am having a problem with. two problems really:
1) I need to search for a line that has the indicated account number
and effectivedate. I have found that this code will not take into
account the effective date.
2)I have tried without the effective date and it will find the
account number, but also finds any accounts that start with the account
number begining "pattern" as well. i need it find JUST the accounts
that match EXACTLY. e.g. user wants to delete account 123456, code
deletes 123456 AND 1234567.

Thank you so much for any suggestions. I love working in PERL and hope
to have more time to study it, but I need to turn this project in ASAP.
Thanks again!
 
P

Paul Lalli

sakuragirl1 said:
I got my first PERL project last Monday

Then this is the time to start forming some good programming practices.

First of all, the language is called "Perl". The program that runs
your Perl scripts is called "perl". There is no "PERL".
and have written 3 pages of
working PERL, but 1 page is driving me nuts! I am very much a newbie,
so please have patience with me. below is a snippet of my code that is
having problems.

open(LISTFILE, "<.ccglist");
open(TEMPFILE, ">.tempfile");

1) Use lexical filehandles, rather than global barewords
2) Use the three-argument form of open
3) Always, yes, *always* check open() for success

open my $LISTFILE, '<', '.cgilist' or die "Can't open cgilist: $!";
open my $TEMPFILE, '>', '.tempfile' or die "Can't open tempfile: $!";
while ($line=<LISTFILE>) {

Always always always start your scripts with the lines
use strict;
use warnings;
right under the shebang. This will force you to declare your
variables, and warn you when you're doing things that are 95% likely to
be wrong....(such as below)

while (my $line = said:
print TEMPFILE $line unless $line =~ (/$accountnumber/ &&
/$effectivedate/);

And here's a problem. If you had enabled warnings, Perl would have
told you that you're using an undefined value in the pattern matches.
Why? Because your && condition is wrong. You are testing whether or
not $line matches the return value of the and'ing of two patternmatches
against $_. You see, when you don't explicitly bind a pattern match to
a variable, it implicitly binds to $_. And that's what you did above,
twice. Your code is equivalent to:

.... unless $line =~ ( ( $_ =~ /$accountnumber/) && ($_ =~
/$effectivedate) );

whereas what you meant was:

.... unless $line =~ /$accountnumber/ && $line =~ /$effectivedate;
}

close TEMPFILE; close LISTFILE;

Put one statement per line. That way, if something goes wrong with one
of the statements, you will be able to tell which one it is, simply
from the error message that Perl gives you.

close $TEMPFILE;
close $LISTFILE;
unlink ".ccglist";

That's not the same filename that you opened above. Are you sure
that's what you meant? This is a good reason to declare a variable,
set it equal to the filename, and then use that variable throughout
your program. That way, 1) 'use strict;' will tell you when you make a
typo, and 2) your program is vastly easier to maintain should you need
to change the name of the file it uses.
rename ".tempfile", ".ccglist";

Again, check return values for *all* system calls:

unlink '.ccglist' or die "Couldn't delete .ccglist: $!";
rename '.tempfile', '.ccglist' or die "Couldn't move tempfile to
ccglist: $!";
I have finally got the deleting of a line working, but it is the
finding i am having a problem with. two problems really:
1) I need to search for a line that has the indicated account number
and effectivedate. I have found that this code will not take into
account the effective date.

Make the changes above, and this problem is solved.
2)I have tried without the effective date and it will find the
account number, but also finds any accounts that start with the account
number begining "pattern" as well. i need it find JUST the accounts
that match EXACTLY. e.g. user wants to delete account 123456, code
deletes 123456 AND 1234567.

You need to anchor your patterns to the start and/or end of the string.
Read
perldoc perlretut
to learn how to do this. At it's most basic, ^ means "start of string"
and $ means "end of string".

if ($line =~ /$number/) {
print "$line contains $number in it somewhere\n";
}

if ($line =~ /^$number/) {
print "$line *starts with* $number\n";
}


On another note, whenever you're trying to match against user-supplied
data, it's a good idea to escape the patterns, just in case the text
the user entered happens to contain characters that are special in
regular expressions:

if ($line =~ /^\Q$number\E/) { ... }

Read about that at
perldoc -f quotemeta
Thank you so much for any suggestions. I love working in PERL and hope
to have more time to study it, but I need to turn this project in ASAP.

This is, in general, a REALLY BAD THING to say in a newsgroup such as
this. Many people will take offense at it. Your (or your company's)
failure to plan or hire someone who already knows the language is not
sufficient reason for us to give you solutions in place of you learning
about the language. Indeed, had I seen this line before I pushed the
"reply" button, there's a good chance I wouldn't have responded at all.
Thanks again!

You're welcome.

Paul Lalli
 
M

Mumia W.

sakuragirl1 said:
[...]
print TEMPFILE $line unless $line =~ (/$accountnumber/ &&
[...]


You might want to match against word boundaries for the account number,
e.g.;

/\b$accountnumber\b/

See "man perlre" as Paul Lalli suggested.
 
M

Matt Garrish

Paul Lalli said:
This is, in general, a REALLY BAD THING to say in a newsgroup such as
this. Many people will take offense at it.

Or tell them to do their own homework. I hope you get credit if she gets an
A... : )

Matt
 
J

Josef Moellers

Matt said:
Or tell them to do their own homework. I hope you get credit if she gets an
A... : )

Let's be fair! Sakuragirl1 (or whatever her name is, assuming it's
indeed a "she") didn't ask to write a complete program, just a simple
detail question.
I, too, frown upon postings that consist of a verbatim copy of the
assignment.
 
P

Paul Lalli

Matt said:
Or tell them to do their own homework. I hope you get credit if she gets an
A... : )

This one was different than the "do this assignment"s we've seen
recently. This OP clearly made a valid attempt at solving the problem,
but didn't know why the code written didn't work correctly. Correcting
faulty code along with explaining why the faulty code was faulty to
begin with is not at all the same as writing a complete program for
someone.

Paul Lalli
 
S

sakuragirl1

I knew after i submitted my post i should not have said what i said in
my last sentence. I tried for 2 days to figure out just that one
section of code and i was really going crazy. Besides being a newbie to
Perl, I am also a newbie poster to newsgroups although I read them all
the time. I should have know better on what to say/ask. I greatly
appreciate your help with my issue Paul.
FYI, here is what i ended up with.

$mainlist=".ccglist";
$templist=".tempfile";

open(LISTFILE, "<$mainlist") or die "Can't open .ccglist: $!";
open(TEMPFILE, ">$templist") or die "Can't open
..tempfile: $!";

while ($line=<LISTFILE>) {
@list= split(/\|/, $line);
print TEMPFILE $line unless $list[0] =~ /^$accountnumber$/ &&
$list[1] =~ /$effectivedate/;
}

close TEMPFILE;
close LISTFILE;
unlink ($mainlist) or die "Couldn't delete .ccgfile: $!";
rename ($templist, $mainlist) or die "Could not rename .tempfile: $!";
 
D

Dr.Ruud

sakuragirl1 schreef:


(I edited & reformatted)

#!/usr/bin/perl
use strict ;
use warnings ;

my $accountnumber = '5019' ;
my $effectivedate = '04/25/62' ;

my $mainlist = '.ccglist' ;
my $templist = '.tempfile' ;

open my $ml, '<', $mainlist
or die "Couldn't open $mainlist: $!" ;

open my $tl, '>', $templist
or die "Couldn't open $templist: $!" ;

while ( my $line = <$ml> )
{
my @list = split /[|]/, $line ;

# See how I used 'eq' and added \Q:
print $tl $line unless $list[0] eq $accountnumber
&& $list[1] =~ /\Q$effectivedate/ ;
}

close $tl
or die "Couldn't close $templist: $!" ;
close $ml
or die "Couldn't close $mainlist: $!" ;

unlink $mainlist
or die "Couldn't delete $mainlist: $!" ;

rename $templist, $mainlist
or die "Couldn't rename $templist to $mainlist: $!" ;
 
P

Paul Lalli

sakuragirl1 said:
I greatly appreciate your help with my issue Paul.
FYI, here is what i ended up with.

$mainlist=".ccglist";
$templist=".tempfile";

open(LISTFILE, "<$mainlist") or die "Can't open .ccglist: $!";
open(TEMPFILE, ">$templist") or die "Can't open
.tempfile: $!";

while ($line=<LISTFILE>) {
@list= split(/\|/, $line);
print TEMPFILE $line unless $list[0] =~ /^$accountnumber$/ &&
$list[1] =~ /$effectivedate/;
}

close TEMPFILE;
close LISTFILE;
unlink ($mainlist) or die "Couldn't delete .ccgfile: $!";
rename ($templist, $mainlist) or die "Could not rename .tempfile: $!";

No use strict, no use warnings, no three-argument form of open, no
lexical filehandles. What is the point of thanking me when you ignore
half of my suggestions? Did you think I made them for the hell of it?
For my own amusement? I was intending to help you become a better Perl
programmer. Your choice to ignore those suggestions pretty clearly
indicates you have no such desire yourself. As such, I feel as though
I have completely wasted my time in responding to you, and will not
trouble myself to do so again.

(Other posters would have just said "*PLONK*". I choose to be more
verbose.)

Paul Lalli.
 
S

sakuragirl1

Well Paul, I did try the things you suggested, but some did not work.
use warning gave the error "could not find warning.pm", and
three-argument form of open gave me a compliation error. I did use
strict but as I only posted a snippet of my code that was not in the
portion i posted, and i did eventually use lexical filehandles after I
determined why i was getting errors when doing so.
I appreciate the help in becoming a better programmer, but if
suggestions do not work, then I try what I can in the environment that
i have. I suppose i could have said "xyz didn't work" but i did not
want to impose any further and felt i could eventually work it out(as i
did with the lexical filehandles). I'm sorry you feel your response to
me was a waste of time.
 
D

DJ Stunks

sakuragirl1 said:
Well Paul, I did try the things you suggested, but some did not work.
use warning gave the error "could not find warning.pm"

use warnings; # plural
three-argument form of open gave me a compliation error.

open my $lexical_fh, '<', $input_filename or die "Could not open
'$input_filename': $!";
I did use
strict but as I only posted a snippet of my code that was not in the
portion i posted,

always post code that you have actually run, from the shebang line
(line #1: #!) to __END__.
and i did eventually use lexical filehandles after I
determined why i was getting errors when doing so.
I appreciate the help in becoming a better programmer, but if
suggestions do not work, then I try what I can in the environment that
i have. I suppose i could have said "xyz didn't work" but i did not
want to impose any further

remember to use the documentation! you can also "use diagnostics;" to
get more detailed information when your program does not compile.

Make _every attempt_ to troubleshoot your problems before reposting,
then post a _short, but complete_ copy of the script and you will
receive prompt, accurate, helpful advice. If you don't understand the
advice, go back to the beginning of the process and try to figure it
out yourself.

-jp
 
M

Matt Garrish

DJ Stunks said:
use warnings; # plural

Could also be an old version of Perl (since I take it the above is not
copied verbatim). The warnings pragma hasn't been around forever.

Matt
 
M

Matt Garrish

Paul Lalli said:
This one was different than the "do this assignment"s we've seen
recently. This OP clearly made a valid attempt at solving the problem,
but didn't know why the code written didn't work correctly.

Granted, but something about the phrase "turn this project in" set off
schoolbells in my head...

Matt
 

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

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,561
Latest member
gjsign

Latest Threads

Top