Writing Files and Associative Arrays

Here’s an example that demonstrates how to create an output file, and how to use associative arrays. A normal array uses numbers (as in $parts[4]) while an associative array can use strings to access the data stored in it. This version of the script reads in the entire password file, building an associative array, where the array index is the loginID, and the value is the real name. This version of the script also takes a command line argument, and uses it to find the real name. This is done by using the input as an index into the associative array. This script also creates an output file, instead of printing the answer to the screen.

 

#!/usr/bin/perl

#ex6.pl

if ($#ARGV == -1)

{

print "USAGE: $0 <userID>\n";

exit;

}

else

{

$login = $ARGV[0];

}

open (IN,"/etc/passwd");

while ($line=<IN>)

{

chop($line);

@parts = split(/:/,$line);

$userinfo{$parts[0]} = $parts[4];

}

close IN;

 

open(OUT,">data");

{

print OUT "$userinfo{$login}\n";

}

close OUT;

 

 

 

 

 

 

Syntax:

end lines with a semi-colon ";"

use curly braces "{" and "}"around code segments

$_ is the default variable used by many functions (chop, split, print, etc)

 

Variables:

most variables start with a "$"

lists start with an "@"

@chars=split(//);

"associative" arrays use curly braces - associative arrays use strings as their indexes into an array

$dev = "c0t0d0s6";

$tfilesys{$dev} = "dump";

 

concatenating strings with the "." operator

$fname="/".$mname."/home/data/sybase.devices";

 

Conditionals:

formatting includes parentheses around the condition, curly braces around the "action"

if ($mname eq "limbsbk1")

{

$omach = "bk3";

}

elsif ($mname eq "limbsbk2")

{

$omach = "bk4";

}

 

numeric

string

meaning

==

eq

equal to

!=

ne

not equal to

>

gt

greater than

>=

ge

greater than or equal to

<

lt

less than

<=

le

less than or equal to

 

Opening files:

for reading:

a static filename

open (IN,"/tmp/vfstab.other");

a variable filename

$fname="/".$mname."/home/data/sybase.devices";

open (IN,"$fname");

reading the output of an external command (note the "|" at the end)

open(IN,"uname|");

reading the output of an external command with a variable in it

open (IN,"/usr/bin/remsh $omach /usr/sbin/swap -l |");

for writing (note the ">" at the beginning)

open (OUT,">/tmp/slices2.dat");

 

Closing files

close IN;

close OUT;

 

Reading From Files

the default method, stores the line that is read in $_

while(<IN>)

{

chop;

$mname = $_;

}

I prefer to read the line into a variable with a name of my choosing

while ($line=<IN>)

{

chop($line);

}

The chop command removes the newline from the end of the input.

 

Writing to files:

The standard printf commands are used, with the filehandle

print using the "default" formatting

printf OUT "$device $save $line\n";

print using specified formats

printf OUT "%8s %3d %30s\n", $device, $save, $line;

 

Split:

The split command breaks a "string" into parts, making the breaks at the specified character or characters. Those familiar with the unix cut command will see many similarities. Regular expressions are useful for more complicated definitions of where to make the break.

The format of the statement is:

 

(<part1>,<part2> ... <partN>)=split(<what to split on>,<what to break into parts>):

 

break $device into 4 parts, making the break at a "/"

($j5,$j6,$j7,$dev) = split(/\//,$device);

break $line into 5 parts, making the break at one or more spaces ([ ]+ is a regular expression)

($j,$dbname,$dbsize,$device,$lname,$devsize)=split(/[ ]+/,$line);

break $line into 3 parts, making the break ar one or more spaces or tabs (\t = a tab)

($j1,$j2,$filesys)=split(/[ \t]+/,$line);

break $g2 into two parts, making the break at either a space or a colon

($junk,$num)=split(/[ \:]/,$g2);

 

 

PREV Perl part 2