Solved

Perl errors help

Posted on 2011-02-27
6
354 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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
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…

820 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