Computing.Net > Forums > Unix > Perl: Split Function & Other Proble

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

Perl: Split Function & Other Proble

Reply to Message Icon

Name: Tina
Date: December 9, 2003 at 20:52:31 Pacific
OS: WIN98
CPU/Ram: 64K
Comment:

I could really use some help on this code as I have been working on it day and night for days now.

Basically, what I am trying to do is 1) Read the file "usernames" into an array and print (usernames was created from field #4 of ourpasswd); 2) Read the file "ourpasswd" into an array and use the split function, using ":" as the field delimiter, to perform various tasks including the following: a) print out to total number of records, b) print out duplicated user names with the number of records for each such name, and c) the percentage of records corresponding to all duplicates in total number of records.

Here's what I've come up with so far:

#!/usr/bin/perl

#open file usernames

open (INP, "usernames") || die ("Cannot open file");
@file=<INP>; #create array
while($file=<INP>) {$table{$line}=0; } #initialize table
print "List usernames file:\n\n "; #print contents
print @file;

#open file ourpasswd

open (INFILE, "ourpasswd" ) || die ("Cannot open file") ;
@line=<INFILE>; #create array
$counter=0; #set counter to zero

while ($line=<INFILE>)
{
$table{$line}=0;
if($line[4]!~/^$/)
{
$table{$line[4]}++;
}
$counter = $counter + 1;
}

print ("There are $counter records in the file\n");

close(INP);

close(INFILE);


I'm not sure if I've got the while loops set up correctly and I am also having trouble figuring our the split function. I've also done some testing on printing the variables but that's not working either. I'm stuck!!! Any help would be greatly appreciated.

Thanks.



Sponsored Link
Ads by Google

Response Number 1
Name: FishMonger
Date: December 10, 2003 at 08:50:17 Pacific
Reply:

My first recommendation would be to enable warnings and use the strict pragma. So, the beginning of the script would look like this:

#!/usr/bin/perl -w

use strict;

#open file usernames

This will allow you to see several of the problems and forces you to declare your vars (which helps to maintain proper scoping of the vars). From what you're describing, since the usernames file is extracted from the "ourpasswd" file, there is no need to read-in both files (unless it's a requirement for a homework assignment). Here's an example of how to use split (within the loop).

@fields = split /:/, $line;

I'm late for work so, I'll check back-in later with more info/help.


0

Response Number 2
Name: ChrisS
Date: December 10, 2003 at 08:59:30 Pacific
Reply:

Tina,

Can you give me a better idea of the file contents and their format as I'm not sure what you are trying to achieve using split.



0

Response Number 3
Name: Tina
Date: December 10, 2003 at 11:22:58 Pacific
Reply:

Fishmonger/Chris:

Thank you both for responding. First of all I did not submit a complete copy of my code. Here is a more current copy of what I've got thus far:


#!/usr/bin/perl

#open file usernames\

open (INP, "usernames") || die ("Cannot open file");
@file=<INP>; #create array
while($file=<INP>) {$table{$line}=0; } #initialize table
print "List usernames file:\n\n "; #print contents
print @file;

#open file ourpasswd

open (INFILE, "ourpasswd" ) || die ("Cannot open file") ;
@line=<INFILE>; #create array
$counter=0; #set counter to zero

while ($line=<INFILE>)
{
$table{$line}=0;
@line=split(/:/,$item);
if($line[4]!~/^$/)
{
$table{$line[4]}++;
}
$counter = $counter + 1;
}

print ("There are $counter records in the file\n");

close(INP);

close(INFILE);


Also, here is a partial copy of the contents of the "ourpasswd" file so you can get an idea of what I'm working with:

root:x:0:1:Nova System Administrator (root):/root:/sbin/sh
system:x:0:1:Nova System Administrator:/users/systems/system:/bin/tcsh
daemon:x:1:1:0000-Admin(0000):/:/bin/false
bin:x:2:2:0000-Admin(0000):/usr/bin:/bin/false
sys:x:3:3:0000-Admin(0000):/:/bin/false
adm:x:4:4:0000-Admin(0000):/var/adm:/bin/false
lp:x:71:8:0000-lp(0000):/usr/spool/lp:/bin/false
smtp:x:0:0:Mail daemon user:/:/bin/false
uucp:x:200:5:0000-uucp(0000):/usr/lib/uucp:/bin/false
nuucp:x:9:9:0000-uucp(0000):/var/spool/uucppublic:/usr/lib/uucp/uucico
listen:x:37:4:Network Admin:/usr/net/nls:/bin/false
dns:x:53:53:BIND User:/usr/local/named:/bin/false
nobody:x:60001:60001:uid no body:/:/bin/false
noaccess:x:60002:60002:uid no access:/:/bin/false
ftp:x:102:102:Anonymous FTP user:/usr/local/ftp:/bin/false
umucftp:x:103:103:UMUC anonymous FTP user:/:/bin/false
mysql:x:108:108:Mysql User:/usr/local/mysql:/bin/tcsh
snmp:x:161:161:ucd-snmp user:/dev/null:/bin/false
cm140o08:x:60209:60200:Mariana G Cabrera:/class/cm140o/08:/bin/tcsh
cm160e06:x:30207:30200:Mariana G Cabrera:/class/cm160e/06:/bin/tcsh
cm435g01:x:61802:61800:Mariana G Cabrera:/class/cm435g/01:/bin/tcsh


The "username" file is extracted from the "ourpasswd" file via a script asg6perl as shown below:

#!/usr/bin/ksh
cd
cd ../share
cat ourpasswd > $HOME/Assignment6/ourpasswd
cd $HOME/Assignment6
cut -d: -f5 ourpasswd > allusernames
egrep -v "^ " allusernames > usernames
uniq usernames > temp
cat temp > usernames
perl asg6.pl ourpasswd


Hopes this helps you to understand better what I am working with. Again, I'm not sure if I've got the while loops set up correctly and I am also having trouble figuring out the split function. I've also done some testing on printing the variables but that's not working either. I'm still stuck!!! Any help would be greatly appreciated.

Thanks again :)


0

Response Number 4
Name: ChrisS
Date: December 10, 2003 at 15:36:53 Pacific
Reply:

OK..
I am looking at the piece of code starting from #open file ourpasswd

you open the file giving it a file handle
<INFILE>

Then you attempt to put it in a list:
@line=<INFILE>;

Then start your loop with the file handle again.. ignoring the poor list!:
while ($line=<INFILE>)

So you are now examining the file line by line each time putting it in the variable $line.

from here you can start splitting the variable into a list of fields..

Heres a start:
##################################

$maincounter=0; #set the counter to zero

#open the file or create error
open (INFILE,"ourpasswd.txt") or die("Could not open file [ourpasswd.txt].");

#read the file line by line
while ($line = <INFILE>) {
chomp($line); # remove the newline char from $line.

(@fields)= split(/:/,$line); # split var into list

#lets see what we have in field 4
print "DEBUG: field name is: [$fields[4]]\n";
$maincounter++;
}
#Fallen out of loop and print total count
print "total count = [$counter]";

################################

Now you can start counting the results of the field with your if statement.

I would use a hash to count these


0

Response Number 5
Name: ChrisS
Date: December 10, 2003 at 16:49:19 Pacific
Reply:

If you get stuck the following may help:
(copy and paste to a txt file and it will be more user friendly:))
If you need me to explain it just shout!

################################

#!/usr/bin/perl -w
use strict;

my $maincounter=0; #set the counter to zero
my $line; #var to hold file line while processing
my @fields; #list to hold split line var
my %user; #Hash to count usernames
my $duplicates; #Var to count the totalnumber of duplicate
my $percent; #Var to calculate the percentage of duplicates

#open the file or create error
open (INFILE,"ourpasswd.txt") or die("Could not open file [ourpasswd.txt].");

#read the file line by line
while ($line = <INFILE>) {
chomp($line); # remove the newline char from $line.

(@fields)= split(/:/,$line); # split var into list

#if field 4 has a value then add it to the array $user
if ($fields[4]){
$user{$fields[4]}++;
}
$maincounter++; #end of processing this line increment counter
}#end of while

$duplicates = 0;# declare var and set to 0

#for each name in the hash "user", if the count is greater than 1 it is a duplicate so print
foreach $a(keys %user){
if ($user{$a}>1){
print "count for duplicate user [$a] is [$user{$a}]\n";

$duplicates = ($duplicates+($user{$a}-1)); # add to total duplicate count (minus 1 because 3 entries means only 2 duplicates)
}#end of if
}#end of foreach

$percent = (100/$maincounter)*$duplicates;#calculate percentage from results above

#Lets print our results:
print "\ntotal count = [$maincounter]\n";
print "total number of duplicates = [$duplicates]\n";
print "percentage of duplicates = [$percent]\n";

close INFILE;#job done

####################################


0

Related Posts

See More



Response Number 6
Name: FishMonger
Date: December 10, 2003 at 20:39:04 Pacific
Reply:

Chris,

Since this is clearly a homework assignment, we're only allowed to guide Tina so that she can learn by writing the script herself. By rewriting and providing an entire (homework) script, you violate computing.net's user agreement. If Tina submits your rewrite as her work, it's plagiarism which helps no-one.


0

Response Number 7
Name: ChrisS
Date: December 11, 2003 at 01:49:50 Pacific
Reply:

Ohppps.. Sorry I didn't realise.



0

Response Number 8
Name: Tina
Date: December 11, 2003 at 13:19:08 Pacific
Reply:

Chris -- thank you for your help. I haven't had a chance to really look over your response yet but I will take a look at it this evening or tomorrow. I just wanted to post a response to let you know that I appreciate your help. I also sincerely appreciate your taking the time to explain the code with all of your comment inserts.

Fish -- I can appreciate your concerns about plagarism. Actually, my assignment was due a couple of days ago (Tuesday by midnight). After the due date of every assignment the instructor usually gives tips (very obvious tips in which sometimes he just comes right out and tells us what to do) to help revise/complete the assignment and, once complete, deducts 11 points from the total score for being late. At any rate, I agree with your remarks.

To the both of you, thanks again.


0

Sponsored Link
Ads by Google
Reply to Message Icon






Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Unix Forum Home


Sponsored links

Ads by Google


Results for: Perl: Split Function & Other Proble

Having troubles with PERL www.computing.net/answers/unix/having-troubles-with-perl/6743.html

Returning file permissions in Octal www.computing.net/answers/unix/returning-file-permissions-in-octal/4790.html

What changes atime on Unix files? www.computing.net/answers/unix/what-changes-atime-on-unix-files/4802.html