| Link | Description | Commands Used |
| Lists and Array Variables | Relation between lists and Array Variables | array list @A = (i, j, k); |
| Access Array Elements | Array Subscripts and Scalar Variables | $A[i], -n<=i<=n |
| Brackets | Brackets with Array Variables | ${array}[0] $array\[0] $array" . "[0] |
| List Range Operator | Using the List range operator with Array Variables | (a..z); |
| Copying Arrays | Making a copy of an Array | @A2 = @A1 = (1, 2, 3); |
| Assigning Scalars | Assigning Scalar variables from Array Elements | ($1, $v2, $v3) = @A; |
| List extents | List Length and List Maximum Subscript | Length: $v = @A; Max Subscript: $v = $#A; |
| Array Slices | Extracting subsets of Array Elements | @slice = @A[1,2,3]; |
| Slice Ranges | List Range operator in Array Slices | @A[0..4] means @A[0,1,2,3,4] |
| Overlapping Slices | Using Array slices on either side of = | @A[1, 2] = @A[2, 3]; |
| Slice Notation | Slice Notation possibilities | @A[1, 2] = @A[2, 1]; |
| Reading <STDIN> | Arrays and <STDIN> | @A = <STDIN>; |
| Functions | Functions used with Arrays | sort(), reverse(), chop(), chomp(), join(), split() |
| Debugging 1 | Debugging Exercise | |
| File System Access | Opening, processing and closing files | open(), close(), die() |
| File Test Operators | File Test Operator list | form: -x expression |
| Global Variables | Global Variables for output | $, $\ $" |
31. Lists and Array Variables
o A list is a sequence of scalar values enclosed in parentheses.
e.g. (1, 5.3, "hello", 2) contains 4 elements, each of which is a
scalar value. The empty list is denoted (). Note that 43.2 and
(43.2) are different: the first is a scalar and the 2nd is a list.
o A scalar variable, $var, can always be included as part of the
list. Suppose $var = 26, then the list (17, $var, "string") is
evaluated as (17,26,"string").
o The value of an expression can also be an element of a list.
(17, $var<<2) becomes (17, 104). (17, $var1+$var2) becomes
(17, 0) when $var1 = -26.
oString Substitution: Since Character strings are scalar values,
they can be used in lists and scalar variable names may be
substituted for in character strings in lists.
($var, "The answer is $var") becomes (26, The answer is 26)
o You may store lists in special variables called array variables.
@array = (1,2,3); {@ is the designation for the array variable.}
variable naming:@ then 2nd character is a letter, others are
letters, digits or underscore. all other characters are illegal.
legal array variable names: illegal array variable names
@my_array @1array
@list2 @_array
@a_very_long_name @a.new.array
o Note that scalar variable names ($var) are in a different name
space than array variables (@var).
32. Accessing Array Variable elements:
o Use subscripts (zero based) to access array variable elements:
$scalar = $array[0]; # first element of array called array
# Note: $array[0] is a scalar, hence $ not @
@array = (1, 2, 3, 4);
$array[3] = 5;
print ("array values are: " @array);
# output is:
array values are: 1 2 3 5
o The Rule: Things that reference one value (scalar variables and
array elements) must start with a $.
o @array = (1, 2, 3, 4);
$scalar1 = $array[4];
$scalar2 = $array[-1]; # last element is assigned
print ($scalar1, "\t");
print ($scalar2);
# output is null string for each:
4
o There is no bounds checking:
@array = (1, 2, 3, 4);
$index = 4;
$scalar = $array[$index]
# output is null definition of scalar and no error message.
33. Examples:
$ cat program12.perl
#! /usr/bin/perl
# a program that prints the elements of a list
@array = (1, "Chicken", 1.23, "\"Having fun?\"", 9.33e+23);
$count = 1;
while ( $count <= 5 ) {
print ("Element $count is $array[$count-1]\n");
$count++;
}
$ program12.perl
Element 1 is 1
Element 2 is Chicken
Element 3 is 1.23
Element 4 is "Having fun?"
Element 5 is 0.3300000000000005+e23
$ cat program13.perl
#! /usr/bin/perl
# a program that generates random integers between 1 and 10
# produce the random numbers and save
$count = 1;
while ( $count <= 100) {
$randnum = int ( rand(10) ) + 1; #rand outputs floating values
# between 0 and 1; then # multiplies it by 10. int
# truncates the result to be 0-9
$randtotal[$randnum] += 1; # $randtotal is initially "" then
# converted to 0 to get updated # by 1
$count++;
}
# output the total of each number
$count = 1;
print ("Total for each number: \n");
while ( $count <= 10 ) {
print ("\t number $count: $randtotal[$count]\n");
$count++;
}
$ program13.perl
Total for each number:
number 1: 11
number 2: 8
number 3: 13
number 4: 6
number 5: 10
number 6: 9
number 7: 12
number 8: 11
number 9: 11
number 10: 9
34. Using Brackets as Brackets with arrays
When both @array and $array are defined and you wish to print $array[0] and not the array's first element, then specify:
"${array}[0]" "$array\[0]" or "$array" . "[0]"
context is array \[ not 1st element . is concatenation operator
Note that "$\{var}" contains the text ${var} explicitly
35. The List Range Operator ..
o (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) is equivalent to (1..10) using the list range operator ..
Other usages:
(1, 5..7, 10) becomes (1, 5, 6, 7, 10)
(2.1..5.3) becomes (2.1, 3.1, 4.1, 5.1)
(4.5..1.6) becomes () since ascending order of operands required
(3..3) becomes (3)
$var1 = 7;
$ var2 = 4;
($var1..$var2+5) becomes (7,8,9)
o Example:
$ cat program14.perl
#!/usr/bin/perl
# A program that uses list ranges to print a list of numbers
print ("Enter the starting number:\n");
$start = <STDIN>;
chop($start);
print ("Enter the ending number:\n");
$end = <STDIN>;
chop($end);
@list = ($start..$end);
$count=0;
print ("Here is the list:\n");
while ($list[$count] != 0 || $list[$count-1] == -1 ||
$list[$count+1] == 1) {
print ("$list[$count]\n");
$count++;
}
$ program14.perl
Enter the starting number:
-2
Enter the ending number:
2
Here is the list:
-2
-1
0
1
2
35. Copying arrays
The list stored in @array1 is copied to the array variable @array2.
Each element of the 1st array is the same as the corresponding element
of the 2nd array.
@array2 = @array1 # @array1 elements already defined
@array2 = @array1 = (1, 2, 3);
@list1 = (2, 3, 4);
@list2 = (1, @list1, 5); # meaning (1, 2, 3, 4, 5)
$ cat program 15.perl
#!/usr/bin/perl
# A program that assigns a list as part of another list
@lotus = (1, 2, 3);
@innerlist = " never ";
@outerlist = ("I", @innerlist, "fail!\n");
print (@outerlist "\n");
print (@lotus "\n");
print ("@lotus", "\n"); # print "@lotus"; also works without ()
$ program 15.perl
I never fail!
123
1 2 3
36. Assigning Scalars from Array variables
$var1=7;
$var2=5;
@array = ($var1, $var2);
($var3, $var4, $var5) = @array;
print ("$var3", "$var5", "$var4");
# output is: 7 5 and $var5 is null string
($var3, $var4) = (7, 5, 3); # assigns multiple scalar variables via a list
# the third element of the list, 3, remains unassigned.
37. Retrieving the length of a list
@array = (7, 5, 1);
$scalar = @array;
#output is the number of elements or length (3) of a list.
Note that the following have different effects:
$scalar = @array; # $scalar = 3
($scalar) = @array; # ($scalar) = (7)
$scalar = (7, 5, 1); # $scalar = 1 3 scalars separated by comma op.
# so $scalar = 7, then = 5, finally = 1)
Another Note: You can get the highest subscript of an array using the following
notation: @a = (1,2,3); $#a will output the subscript of the highest element of array @a
This is the same as the total number of elements of the array minus one, since 0 based
subscripting is used.
For Example: $ perl -e '@a = (1, 2, 3); $a[6] = 7; $c = @a; $b = $#a; print "$c $b \n";'
7 6
Example: Print the contents of an array
@array = (a..z);
$i = 0;
while ($I <= $#array) {
print $array[$i++], "\n";
}
If you deliberately modify the value of $#array to be:
larger than actual: implies the added elements are all undefined;
smaller than actual implies that the truncated elements are discarded;
Scalar Context - The Rule: For $numelements = @arrayname;
The left side has a scalar variable, so the assignment is operating in a scalar context
thus the array representing the list evaluates to the number of elements in the array,
a single value.
Boolean Context - The Rule: Lists that have any elements, including
undefined elements, are considered true in a Boolean Context. An empty list
is considered false.
Scalars in a Boolean context are true if non-zero and false if zero, null,
or undefined.
Functions and Parentheses - The Rule. Functions also operate with their
arguments evaluated in context. If you supply a parenthesized set of arguments to
that function, the evaluation is straightforward based on the argument given.
If you supply a comma separated set of arguments, without parentheses, Perl builds
a list from those arguments. But which is safer?
print 4 + 5, 6, 'foo';
print (4 + 5), 6, 'foo';
print ((4 + 5), 6, 'foo');
o The scalar() function
To force a list to be evaluated in a scalar context, use the scalar function. Compare:
print @num;
print scalar(@num);
The print statement evaluates its arguments in a list context by default.
$ cat program16.perl
#!/usr/bin/perl
# A program that prints every element of an array
@array = (14, "cheeseburger", 1.23, -7 "I give up");
$count = 1;
while ($count <= @array) { # @array means its length
print ("Element $count: $array[$count - 1]\n");
$count++;
}
$ program16.perl
Element 1: 14
Element 2: cheeseburger
Element 3: 1.23
Element 4: -7
Element 5: I give up
38. Using Array Slices
@array = (7, 5, 3);
$array[3] = 1;
@subarray = @array[2,3]; # 3rd, 4th elements of @array
# @array[2,3] is an array slice
@slice = @array[1,2,3]; # array assignment references get @
$slice = $array[0]; # scalar assignment references get $
$ cat program17.perl
#!/usr/bin/perl
# A program that prints every element of an array
@array = (14, "cheeseburger", 1.23, -7 "I give up");
@subarray = @array[1,2];
print ("The first element of subarray is $subarray[0]\n");
print ("The 2nd element of subarray is $subarray[1]\n");
$ program17.perl
The first element of subarray is cheeseburger
The 2nd element of subarray is 1.23
39. Using list ranges in Array Slice subscripts
@array[0, 1, 2, 3, 4] can be written as @array[0..4] using ..
when $endrange = 4;
@subarray = @array[0..$endrange]; # variables work in subscripts
$ cat program18.perl
#!/usr/bin/perl
# A program that uses an array variable as an array slice subscript
@array = (14, "cheeseburger", 1.23, -7 "I give up", 0);
@range = (1, 2, 3);
@subarray = @array(@range);
print ("The array slice is @subarray\n"); # "@subarray" -> contents
# @subarray -> concatenated contents
$ program18.perl
The array slice is cheeseburger 1.23 -7
You can assign to array slices via:
@array[0,1] = ("string", 46);
@array[0..3] = (1, 2, 3, 4);
$beginrange = 0;
$endrange = 5;
@array[$beginrange..$endrange] = (1, 2, 3, 4); # @array[5] = ""
$endrange = 2;
@array[$beginrange..$endrange] = (1, 2, 3, 4); # last list item ignored
$ cat program19.perl
#!/usr/bin/perl
# A program that assigns to an array slice
@array = ("old1", "old2", "old3", "old4");
@array[1,2] = ("new1", "new2");
print ("The array contents is @array\n");
$ program19.perl
The array contents is old1 new1 new2 old4
40. Overlapping Array Slices
You can use array slices on either side of an assignment statement
@newarray = @array[2, 3, 4];
@array[2, 3, 4] = @newarray;
This allows array slices to be assigned to each other, even if they overlap.
@array[1, 2, 3] = @array[2, 3, 4]; # since the list is stored in
# memory during the assignment
e.g. @array = ("one", "two", "three", "four", "five");
@array[1, 2, 3] = @array[2, 3, 4];
print ("@array\n");
# output is:
one three four five five
Note that mismatched lengths are handled as above (empty ignorance)
e.g. @array[0..2] = @array[3, 4];
The value of the array is now:
("four", "five", "", "four", "five")
41. Array Slice notation
In perl, there is no difference between an array slice and a list containing consecutive elements of the same array. Thus
@subarray = @array[0, 1];
@subarray = ($array[0], $array[1]);
So you can refer to any elements of an array in any order. e.g.:
@subarray = ($array[4], $array[1], $array[3]);
@subarray = @array[4, 1, 3];
@subarray = @array[0, 0, 0]; # yeilds first element 3 times
@array[1, 2] = @array[2, 1]; # swap elements 2 and 3
$ cat program20.perl
#!/usr/bin/perl
# A program that sorts an array
print ("Enter the array to sort, one item at a time.\n");
print ("Enter an empty line to quit.\n");
$count = 1;
$inputline = <STDIN>;
chop ($inputline);
while ( $inputline ne "" ) {
@array[$count-1] = $inputline;
$count++;
$inputline = <STDIN>;
chop ($inputline);
}
# Do the sorting
$count = 1;
while ( $count < @array ) {
$x = 1;
while ( $x < @array ) {
if ($array[$x-1] gt $array[$x]) {
@array[$x-1,$x] = @array[$x,$x-1];
}
$x++;
}
$count++;
}
print ("@array\n");
$ program20.perl
Enter the array to sort, one item at a time.
Enter an empty line to quit.
foo
baz
dip
bar
sty
bar baz dip foo sty
A one liner using the sort function:
@array2 = sort(@array);
# This sorts (strings) alphabetically in ascending order.
42. Reading an Array from <STDIN>
$ cat program21.perl
#!/usr/bin/perl
# A program that reads data into an array and writes that array
@array = <STDIN>;
print (@array);
$ program21.perl
This is line 1
This is the second line
This is the last line
<Ctrl-D>
This is line 1
This is the second line
This is the last line
$
43. Array Library functions
o sort Sorting a list or Array variable
sortedlist = sort ( array ); # array and sortedlist are both arrays.
@array = ("this", "is", "a", "sentence");
@array2 = sort (@array);
print ("@array2");
# @array2 contains the sorted list: ("a", "is", "sentence", "this")
# output is the sorted list: a is sentence this
sort (@array); # doesn't do anything because it is not assigned
@array = (70, 100, 8);
@array2 = sort (@array);
# @array2 contains (100, 70, 8) in ascii order
The sort() function for ascii ascending ordered sorts uses the explicit ordering:
sort { $a cmp $b} @asciiarray; # same as sort @asciiarray
For numerical ascending sorts, use the explicit ordering:
sort { $a <=> $b} @numarray;
o reverse Reverses the order of elements of a list or array variable
reversedlist = reverse ( array ); # array and reversedlist are both arrays.
$ cat program22.perl
#!/usr/bin/perl
# A program that sorts in reverse order
@input = <STDIN>;
@input = reverse ( sort (@input));
# alternatively: @input = reverse sort (@input); is permitted
print (@input);
$ program22.perl
foo
bar
dip
baz
sty
<Ctrl-D>
sty
foo
dip
baz
bar
$
o chop and chomp revisited
chop removes the last character of each element of a list and returns
that character.
@list = ("rabbit", "12345", "quartz");
chop (@list);
# @list now contains ("rabbi", "1234", "quart")
Use chop on arrays generated from <STDIN>
chomp removes the line endings (newlines) from all elements of a list
and returns the number of such removals.
@list = ("rabbit", "12345", "quartz");
chomp(@list)
# @list is unchanged
chomp doesn't tamper with the character strings like chop does. Use
chomp on arrays generated from <STDIN> or not.
o join creates a simple string from a list of strings, which can then
be assigned to a scalar variable.
string = join (array); string is a character string; array is a list (1st
element of array is "field" separator for the rest).
$string = join (" ", "this", "is", "a", "character", "string");
# $string contains: this is a character string
@list = ("here", "is", "a");
$string = join (" ", @list, "string");
# $string contains: here is a string
$ cat program23.perl
#!/usr/bin/perl
# A program that converts an array to a string using join
@input=<STDIN>;
chop (@input); # or chomp (@input);
$string = join (" ", @input);
print ("$string\n");
$ program23.perl
This
is
my
input
<Ctrl-D>
This is my input
$
o split creates an array or a list from a character string
array = split (/pattern/, string); string is a character string;
array is a list; pattern matches the
"field" separator in the string).
$string = "words::separated::by::colons";
@array = split ( /::/, $string );
# @array contains the list: ("words", "separated", "by", "colons")
$ cat program24.perl
#!/usr/bin/perl
# A program that does a simple word count
$wordcount = 0;
@line=<STDIN>;
while ( $line ne "" ) {
chop($line); # or chomp ($line);
@array = split(/ +/, $line); # + is a reg exp character
# matches 1 or more of previous
# character.
$wordcount += @array;
$line = <STDIN>
}
print ("Total number of words: $wordcount\n");
$ program24.perl
Here is some input.
Here are some more words.
Here is my last line.
<Ctrl-D>
Total number of words is 14
$ cat program25.perl
#!/usr/bin/perl
# A program that reverses the word order of the input file
@input = <STDIN>;
chop(@input);
# First reverse the order of words on each line
$currline = 1;
while ( $currline <= @input ) {
@words = split (/[ \.\!\?]+/, $input[$currline-1] );
@words = reverse (@words);
$input[$currline-1] = join(" ", @words, "\n");
$currline++;
}
# Now reverse the order of the input lines and print them
@input = reverse (@input);
print (@input);
$ program25.perl
This sentence
is in
reverse order.
<Ctrl-D>
order reverse
in is
sentence This
$
44. Debugging Corner: What's wrong here?
$result = @array[4];
----------------------------------
#!/usr/bin/perl
@input = <STDIN>;
$currline = 1;
while ( $currline < @input ) {
@words = split(/ /, $input[$currline]);
@words = sort (@words);
$input[$currline] = join (" ", @words);
$currline++;
}
print (@input);
-----------------------------------
#! /usr/bin/perl
print 'Enter list of numbers: ';
chomp($in = <STDIN>);
@nums = split(" ", $in);
@sorted = sort @nums;
print "Numbers: @sorted\n";
$totalnums = $#nums;
print "Total number of numbers: $totalnums\n";
45. Perl and the File system: Opening files
o open To access a file exclusively
open ( filevar, filename ); where filevar is the variable name that perl
uses to refer to the file (aka file handle) and
filename represents the location in the
filesystem of this file. open returns a success
or failure status value
filevar is named by a letter followed by letters, digits, or underscore.
No reserved words allowed. By convention, use uppercase letters to
distinguish file variables from other variable names and reserved words.
open (FILE1, "file1"); # relative path specification
open (FILE1, "/home/faculty/katz/file1"); # full path specification
# tells perl that it should open the file, file1 (in the current directory)
and associate it with the file variable FILE1
open can work with three modes: read, write (overwrite) and append.
open(FILE1, "file1"); # opens for reading
open(FILE1, ">file1"); # opens for writing
open(FILE1, ">>file1"); # opens for appending
Before using an open file, make sure the open succeeded.
if open returns a non-zero value, the file has been opened successfully
(Boolean Success)
if open returns a zero value, an error has occurred.
test via:
if ( open(MYFILE, "/home/faculty/katz/myfile") ) {
# what to do if file opened successfully
}
o Reading from a file
$ cat program26.perl
if ( open(MYFILE, "/home/faculty/katz/myfile") ) {
$line = <MYFILE>;
while ( $line ne "" ) {
print ($line);
$line = <MYFILE>;
}
}
$ program26.perl
line 1
line 2
line 3
$
o die Terminating a program and sending a message to STDERR
die (message); The program terminates immediately and an (error)
message is printed.
$ cat program27.perl
#! /usr/bin/perl
# exercising the right to die
unless ( open(MYFILE, "/home/faculty/katz/myotherfile") ) {
die ("Cannot open input file '/home/faculty/katz/myotherfile'\n");
}
#unless ( open(MYFILE, "/home/faculty/katz/myotherfile") ) {
# die ("Missing input file");
#}
$line = <MYFILE>;
while ( $line ne "" ) {
print ($line);
$line = <MYFILE>;
}
}
$ program27.perl
Cannot open input file '/home/faculty/katz/myotherfile'
# Missing input file at program27.perl line 2
o Reading into Array Variables
@array = <MYFILE> #entire file contents stored in @array
# one line per element
o Writing to a File
open (OUTFILE, ">outfile");
print OUTFILE ("Here is an output line.\n");
$ cat program28.perl
#! /usr/bin/perl
# a program which copies one file to another
unless (open(INFILE, "file1") ) {
die ("Cannot open file 'file1'\n");
}
unless (open(OUTFILE, "file2") ) {
die ("Cannot open output file 'file2'\n");
}
$line = <INFILE>;
while ($line ne "") {
print OUTFILE ($line);
$line = <INFILE>;
}
$ program28.perl
$
o Merging (Shuffling) two files
$ cat program29.perl
#! /usr/bin/perl
# a program which merges two files with interleaved lines
open(INFILE1, "file1") || die ("Cannot open file 'file1'\n");
open(INFILE2, "file2") || die ("Cannot open file 'file2'\n");
print STDERR ("File 'file1' and 'file2' opened successfully.\n")
$line1 = <INFILE1>;
$line2 = <INFILE2>;
while ($line1 ne "" || $line2 ne "" ) {
if ( $line1 ne "" ) {
print ($line1);
$line1 = <INFILE1>;
}
if ( $line2 ne "" ) {
print ($line2);
$line1 = <INFILE2>;
}
}
$ program29.perl
File 'file1' and 'file2' opened successfully.
a1
b1
a2
b2
a3
b3
a4
$
o Closing files (Done automatically at end of program)
close (filevar); File variable filevar indicates what file is being closed.
open (MYFILE, ">file1");
print MYFILE ("Here is line 1.\n"); # to file1
open (MYFILE, ">file2"); # MYFILE is closed automatically first
print MYFILE ("Here is another line1.\n"); # to file2
close (MYFILE); #MYFILE is closed explicitly
46. File Test Operators
-x expr where x is an alphabetic character; expr is an expression
-b Is expr a block device? Non-zero status if true
-c Is expr a character device?
-d Is expr a directory?
-e Does expr exist?
-f Is expr an ordinary file?
-g Does expr have setgid bit set?
-k Does expr have its sticky bit set?
-l Is expr a symbolic link?
-o Is expr owned by user?
-p Is expr a named pipe?
-r Is expr a readable file?
-s Is expr a non-empty file?
-t Does expr represent a terminal?
-u Does expr have setuid bit set?
-w Is expr a writable file?
-x Is expr an executable file?
-z Is expr an empty file?
-A How long since expr accessed?
-B Is expr a binary file?
-C How long since expr's inode accessed?
-M How long since expr modified?
-O Is expr owned by the real user only? (logged in user)
-R Is expr readable by the real user only?
-S Is expr a socket?
-T Is expr a text file?
-W Is expr writeable by the real user only?
-X Is expr executable by the real user only?
$ cat program30.perl
#! /usr/bin/perl
# a program tests for file existence before writing to it
open(INFILE, "file1") || die ("Cannot open file 'file1'\n");
if ( -e "outfile") {
die ("Output file outfile already exists.\n");
}
open(OUTFILE, "file2") || die ("Cannot open file 'file2'\n");
#
# Alternatively:
#open (INFILE, "file1") && !( -e "outfile") &&
# open(OUTFILE, ">outfile") || die("Cannot open file\n");
$line = <INFILE>
while ($line ne "") {
chop ($line);
print OUTFILE ("\U$line\E\n");
$line = <INFILE>;
}
$ program30.perl
$
47. Output Global Variables
Three Global variables affect how lists can be output.
$, This variable, null by default, is the Output field separator. It contains the
characters to print inbetween list elements.
$\ This variable, null by default, is the Output record (line) separator. It contains
characters to print at the end of a list.
$" This variable, single space by default, is like the Output record separator. However,
it specifically affects list variables interpolated inside strings.
Printing bare lists:
$ perl -e 'print(1,2,3);'
123$
$ perl -e '$, = "*"; $\ = "\n"; print (1,2,3);'
1*2*3
$ perl -e '$" = "#"; $\ = "\n"; $, = " "; @var = (a,b,c,d,e); print (0,"ABC@{var}DEF",1);'
0 ABCa#b#c#d#eDEF 1