Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

incorrect Results - Looping through Files & substr () 2

Status
Not open for further replies.

polka4ever

Technical User
Jan 25, 2006
42
0
0
US
Hello,

I am getting incorrect results and I am a newbie - so if you have any ideas, I would greatly appreciate the help!

here is what I have:

#!/usr/local/bin/perl

for (<suspec*.data>)

{ open(INFO, $_) or die "Can't open input file: $!";

while (<INFO>){
chomp;
my $small_string = substr ($_, 209, 6); # this is the houseNumber field
if ($small_string = '844')
{print "$small_string\n";
}
}
close INFO;

}

Basically - I'm running this on Unix - and in the suspec*.data files (which are just two files) I have a total of 11 rows of data. Only ONE row - actually matches the condition of the house number field is equal to '844' BUT - when I run this script, the # 844 is printed 11 times to my screen! What am i doing wrong?

Also - how can i redirect the output of this to a file (instead of to my screen) and also - i'd like to put the whole ROW in my output (not just the substr part) as well as which file it came from. Can anyone help with this?

Thank you!

~Polka

p.s. Happy mardi gras to everyone! (Fat Tuesday/Paczki Day)
 
this line:

if ($small_string = '844')

should be:

if ($small_string == '844')


'=' is the assingment operator, '==' is the numeric comparison operator. The first line above will always be true since you are assigning the value of 844 to $small_string, so it always prints the line/data.
 
Code:
if ($small_string = '844')
is an assignment statement, not a comparison.

Also, you might find it easier to specify the files from the command line
Code:
#!/usr/local/bin/perl
use strict;
use warnings;

while (<>) {
    chomp;
    my $small_string = substr ($_, 209, 6); # this is the houseNumber field
    if ($small_string == '844') {
        print "$small_string\n";
    } 
}
as you can then just
Code:
myscript suspec*.data > out.txt
to send the output to a file.
 
Oh thank you! gosh, what a silly mistake (the assignment operator). I have got to watch that.

Stevexff, I'm not sure I understand:

myscript suspec*.data > out.txt

how does perl know to use the rows instead of just the substr() and also, how can I can I include in there the filename? Sort of like if I were doing a grep -H 844 > out.txt

~polka
 
something like this:

Code:
#!/usr/local/bin/perl

open(OUT,'>>out.txt') or die "$!"; 
for (<suspec*.data>){
   my $file = $_;
   open(INFO, $file) or die "$!";
   while (my $line  = <INFO>){
      chomp;
      substr($line,209,6) == 844 ? print OUT "$file - $line\n" : next;
   }
}
close OUT;
close INFO;
 
When you invoke your script at the command line, the shell expands the suspec*.data into a list of files that match, so it becomes myscript suspect1.data suspect2.data > out.txt. The while (<>) construct causes perl to catenate any files passed on the command line, open them automatically, and read them as if they were one file. The shell redirection operator > causes the output to be written to a file out.txt instead of being sent to the screen.

Which covers the redirection part. I'd missed the
i'd like to put the whole ROW in my output (not just the substr part) as well as which file it came from
in the OP, but it looks like Kevin's already given you a solution...
 
KevinADC, OK that worked like a charm. Wow. I'm impressed. i'm not totally sure how that was constructed or how you knew to do it that way - but I am studying it, to see if I can make more sense of it.

Here's another little complication, what if I want it to be like - in the housenumber range (which you know is 209-214) it's equal to 844, but ALSO in the streetname field it equals (or it includes) the word MAIN (the streetname field is field 219 and has 20 characters).

Thank you also to stevexff for your help!

~p4E
 
just keep adding the other data you need to match in the ternary operator, not sure if this works but you can try and tweak it until it does:

Code:
substr($line,209,6) == 844 and substr($line,219,20) =~ /MAIN/ ? print OUT "$file - $line\n" : next;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top