Solved

Perl errors help

Posted on 2011-02-27
6
349 Views
Last Modified: 2012-05-11
Hello,
Wondering if anyone cam help with with the below error.
This program uses a soundex subroutine, you indicate a lastname
and the program calls system funtion finger and displays the info.
They key is you can misplell the name and it will still pull the user info.

I don't get it since the subroutine soundex works when ran seperate.
I added the corresponding numbers to the lines where the errors are indicated.

Error:
Use of uninitialized value in transliteration (tr///) at ./final4 line 123 (#1)
    (W uninitialized) An undefined value was used as if it were already
    defined.  It was interpreted as a "" or a 0, but maybe it was a mistake.
    To suppress this warning assign a defined value to your variables.

    To help you figure out what was undefined, perl will try to tell you the
    name of the variable (if any) that was undefined. In some cases it cannot
    do this, so it also tells you what operation you used the undefined value
    in.  Note, however, that perl optimizes your program and the operation
    displayed in the warning may not necessarily appear literally in your
    program.  For example, "that $foo" is usually optimized into "that "
    . $foo, and the warning will refer to the concatenation (.) operator,
    even though there is no . in your program.

Use of uninitialized value $fc in substitution (s///) at ./final4 line 124 (#1)
Use of uninitialized value $fc in concatenation (.) or string at ./final4 line
        127 (#1)
Use of uninitialized value $f in concatenation (.) or string at ./final4 line
        129 (#1)

#!/usr/bin/perl
use diagnostics;
use strict;
use warnings;
#use Data::Dumper;

my $num = 0;

 if (@ARGV != 1)

 {
     print "\nUsage: $0 LastName\n\n";
     exit(1);
 }
 chomp $ARGV[0];


#-------------------


open (IN,"/etc/passwd");
my @wholeFile = <IN>;
close IN;

foreach my $line (@wholeFile)
{
    my $userid = &get_user_id($line);
    my $lastname = &get_last_name($line);
  #  print "$userid has a last name of $lastname!\n";

 if(&soundex($lastname) eq &soundex($ARGV[0]))

     {
         my @args = ("finger", $userid);
         system (@args);
         $num++;
     }
}

print "\nThe name you were looking for, ".$ARGV[0]." converted to ".soundex($ARGV[0])."\n";



 if ($num == 0)

     {

         print "finger: ".$ARGV[0].": no such user.\n\n";

     }

#---------------userid----------------------

sub get_user_id

 {
my @uname = grep /^\w.*?/, @wholeFile;
#convert array into string
my $string = join('',@uname);

my @data1 = split (/\n/, $string);

      @data1 = split(/:/,shift);
    # print "$userid[0]";
     return $data1[0];
 }

#-----------lastname-------------

sub get_last_name
 {
my @uname = grep /^\w.*?/, @wholeFile;
#convert array into string
my $string = join('',@uname);

my @data1 = split (/\n/, $string);

      @data1 = split (/:/,shift);

     if ($data1[4] ne "" || $data1[4] ne " ")
     {
         $data1[4] =~ s/,.*?//g;
         $data1[4] =~ /(\S+\s\S+\s*\S*)/g;
         return $1;
     }
     else
     {
         print "No last name provided\n";
     }
 }

 
 

#--------------soundex subroutine---------------------------------------------
sub soundex
{

  my $temp = uc shift;    # gets the name passed to the function
                           # and uppercases it

$temp =~ s/^[^A-Z]//;   # remove first character if not letter

# Eliminate doubled-letters

my @x = split(//,$temp);
$temp = '';
my $lastx = '';

foreach my $x ( @x)
{
    if ( ( $lastx eq '' ) || ( $x ne $lastx ) )
    {
        $temp .= $x;
        $lastx = $x;
    }
}
#print STDERR "$temp\n";

# Split into first letter and the rest
my ($f, $fc) = ($temp =~ /(\w)(\w+)/);
 
# soundex weighting
123 $fc =~ tr/AEHIOUWYBFPVCGJKQSXZDTLMNR/00000000111122222222334556/;
124 $fc =~  s/0+//g; #gets rid of extra 0's

# first four digits, pad with zeroes on right if needed
127 $fc = substr($fc.'000',0,4);   
 
129 my $sdxValue = $f.$fc;

  return $sdxValue;   
    
}

Open in new window

0
Comment
Question by:fac66
6 Comments
 
LVL 16

Expert Comment

by:sjklein42
ID: 34994071
Line 78 is wrong:

      @data1 = split (/:/,shift);

Open in new window

See line 76 also.  These two lines must have a typo or something.  That is the trigger of the error.
0
 
LVL 10

Expert Comment

by:APNFSSC
ID: 34994117
I think you should test to see if a last name is returned by get_last_name, if it's blank then you'll get the error i think.

foreach my $line (@wholeFile)
{
    my $userid = &get_user_id($line);
    my $lastname = &get_last_name($line);
  #  print "$userid has a last name of $lastname!\n";
 unless($lastname){
 print "Lastname empty skipping $userid\n";
next;
 }

 if(&soundex($lastname) eq &soundex($ARGV[0]))

     {
         my @args = ("finger", $userid);
         system (@args);
         $num++;
     }
}

0
 

Author Comment

by:fac66
ID: 34994262
That is it.
The problem is the data I need is at element 4 of the array which is suppose to hold the full name.
Some fields are blank.
Most names have 1st & last, while some have a middle also.
Some people even have 3 or 4 names.
How do I filter the last name?
Any ideas? I have tried several regex filters and cannot get it.
Any help would be appreciated.
sub get_last_name
 {
my @uname = grep /^\w.*?/, @wholeFile;
#convert array into string
my $string = join('',@uname);
#split at newlines
my @data1 = split (/\n/, $string);
      #split at colons
      @data1 = split (/:/,shift);

     if ($data1[4] ne "" || $data1[4] ne " ")
     {
         $data1[4] =~ s/,.*?//g;
         $data1[4] =~ /(\S+\s\S+\s*\S*)/g;
                 return $1;
     }

}

Open in new window

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 10

Accepted Solution

by:
APNFSSC earned 500 total points
ID: 34994278
Let's say your data1 array item 4 has the following in it

$date1[4]='John Paul Smith';

Then you could split that out into another array and choose the last element simular to below... not sure if this will work for you as i cannot see that data you have.

my @name_array = split(/ /,$data1[4]);
$lastname = $name_array[-1];
0
 

Author Comment

by:fac66
ID: 34994315
I need to keep debuging but I think that worked.. thank you!
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 34994454
You have a lot of major problems with that script.

Here are some of the problems.

You have no error handling.

You should ALWAYS check the return code of an open call to make sure it was successful and take action if it wasn't.  You should use a lexical var for the filehandle and the 3 arg form of open.

You're slurring the file into an array and then looping over the array instead of processing the file line-by-line.

For every line in the file file you're passing it to 2 almost identical subroutines each of which do a grep on the entire file each time they're called.

The array that you build from that grep statement is then joined into a single string and then that string is split to create a duplicate of the original array.  Then you throw all that away when you use another split statement to overwrite the array you just created.

There are other issues, but you should address those first.

0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now