Perl Training Session1 22nd Sept 2012
Perl Training Session1 22nd Sept 2012
(Session 1)
Arpit Seksaria
22nd Sept, 2012
Strings
Control flow
Perl hashes
And more ….
You can run the script directly if you make the script
executable, and the first line is of the following form
( #!/usr/... must start from the first column):
$ chmod +x simple.pl
$ cat simple.pl
#!/usr/local/bin/perl5 -w
$ ./simple.pl (or)
$ perl simple.pl (executing script using this, doesn’t require the perl interpreter path)
#!/usr/local/bin/perl5 -w
print "Hello world\n";
The print command sends the string to the screen, and “\n” adds
a newline.
You can optionally use parenthesis around the argument in print:
print ("Hello world\n");
use strict;
$this_data = "Something";
$that_data = "Something Else ";
print "_$this_data_, or $that_datawill do\n";
use strict forces you to declare your variables before using them. Also
controls references & subroutines.
22/09/2012 Mirafra Confidential 13
User Input
<STDIN> grabs one line of input, including the newline character. So,
after:
$name = <STDIN>;
if the user typed “Bill Clinton[ENTER]”,
$name will contain: “Bill Clinton\n ”.
$cat file
print "What is your name? ";
$name = <STDIN>;
chomp ($name);
print “Hello $name !\n”;
Output:
$ ./file
What is your name? Arpit
Hello Arpit !
$
$x=“hello world\n”;
$y=chop($x); # $x is now “hello world”, $y is “\n”
$x = "hello world\n";
$k=chomp($x); # $x is “hello world”, $k is 1
22/09/2012 Mirafra Confidential 16
Strings (Singly quoted) (1)
Examples:
Invalid Strings:
$a = "fred";
$b = “Hi $a”; # $b is now Hi fred
$fred = "pay";
$fredday = "wrong!";
$str = “hello”
$str .= “add"; # $str is now helloadd
22/09/2012 Mirafra Confidential 23
REF
Assignment with operators
use strict;
my $greet = "Hi! ";
$greet .= "Everyone\n";
$greet = $greet . "Everyone\n“; # Does the same operation as the line above
Substring extraction:
substr( STRING, OFFSET[, LEN] [, REPLACEMENT])
$a = “123456789” ;
print substr($a,3); #prints 456789
print substr($a,3,2) #prints 45
substr($a,3,2) = ”World” ;
print $a ; # prints 123World6789
substr($a,3) = ”Ending” ;
print $a ; # prints 123Ending
substr($a,3,2,“World”);
print $a; # 123Worldding
String length:
length STRING
Ex:
$str=“abc”;
$a=length $str;
print $a; # $a is 3
Numerical Example
#!/usr/local/bin/perl5 -w
print "Enter height of rectangle: ";
$height = <STDIN>;
print "Enter width of rectangle: ";
$width = <STDIN>;
$area = $height * $width;
print "The area of the rectangle is $area\n";
Output:
Enter height of rectangle: 10.1
Enter width of rectangle: 5.1
The area of the rectangle is 51.51
$a = 17;
$b = $a + 3; # $b is 20 now
$b = 4 + ($a = 3); # $b is 7 now
$d = ($c = 5); # copy 5 to $c and then 5 to $d
$a += 5; # $a is 8 now
$b *= 3; # same as $b=$b*3
use strict;
my $abc = 5;
my $efg = $abc-- + 5;
# $abc is now 4, but $efg is 10
$a=$b+10;
#use strict wont let you do this !
print $a; #prints 10
The curly braces { } are always required in Perl even if there is only
one statement inside.
$user = `whoami`;
chomp($user);
if ($user eq "clinton") {
print "Hi Bill!\n";
} else {
print "Hi $user!\n";
}
You can also combine and negate expressions with logical and (&&), logical
or (||), and not (!) just like in C++:
chomp($user = `whoami`);
chomp($nme = `who | grep $user | wc -l`);
chomp($nusers = `who | wc -l`);
if($nusers - $nme && $user ne "clinton"){
print "Someone else is logged in!\n";
}
else{
print "All is well!\n";
}
The while statement loops indefinitely, while the condition is true, such as a
user-controlled condition:
$resp = "no";
while($resp ne "yes"){
print "Wakeup [yes/no]? ";
chomp($resp = <STDIN>);
}
while(1){
print "Wakeup [yes/no]? ";
chomp($resp = <STDIN>);
if($resp eq "yes"){
last;
}
}
until (some_expression){
statement_1; statement_2; statement_3;
}
Ex:
$a = 1; # Count from 1 to 10
until ($a > 10) {
print "a = $a\n";
$a++;
}
$count = 10;
do {
print "$count ";
$count--;
} while ($count >= 1);
Output: 10 9 8 7 6 5 4 3 2 1
$count = 10;
do {
print "$count ";
$count--;
} until ($count == 0);
Output: 10 9 8 7 6 5 4 3 2 1
use strict;
my $a = 5; my $b = 500;
$a < $b; # evaluates to 1 true
$a >= $b; # evaluates to "“ false
$a <=> $b; # evaluates to -1 true
my $c = "hello"; my $d = "there";
$d cmp $c; # evaluates to 1 true
$d ge $c; # evaluates to 1 true
$c cmp "hello"; # evaluates to "" false
There is a shortcut for lists of single-word strings, the “quote word” function:
qw(bill
gates
pie
toss) # same as above
The context determines whether the length of the array is used or the list:
$n = @nums; # $n gets the length of @nums
($n) = @nums; # $n gets the first element of @nums
($n1, $n2) = @nums; # first two elements of @nums
You can use all the usual scalar operations on the array
elements:
@a = (1,2,3);
$a[0]++; # a: (2,2,3)
$a[1] += 4; # a: (2,6,3)
$a[2] += $a[0]; # a: (2,6,5)
$c = (1,2,3,4,5)[2]; # sets $c to 3
@b = (1,2,3,4,5)[2,4]; # sets @b to (3,5)
@x = (1,2,3,4,5);
@b = @x[2,4];
@list1 = (5,6,7);
$n = 2;
$m = $list1[$n]; # $m = 7
$p = $list1[$n-1]; # $p = 6
($p) = (5,6,7)[$n-1]; # same thing using slice
@nums = (5,6,7);
@i = (2,1,0);
@rev = @nums[@i];
# same as @nums[2,1,0]
# or ($nums[2], $nums[1], $nums[0])
# or (7,6,5)
@nums = (5,6,7);
$nums[3] = "bill"; # @nums: (5,6,7,"bill")
$nums[5] = "g."; # @nums: (5,6,7,"bill",undef,"g.")
You can use $#bill to get the index value of the last element of @bill.
Accessing an array with a negative subscript counts back from the
end. So, another way to get the last element of @bill is $bill[-1].
You can use push and pop to add and remove values
from the end of an array.
@a = (1,2,3);
$new = 6;
push(@a,$new); # same as @a = (@a,$new)
# so far: (1,2,3,6)
$oldvalue = pop(@a); # removes last element of @a
# so far: (1,2,3)
push(@a,4,5,6); # can push multiple values
# so far: (1,2,3,4,5,6)
pop returns undef if given an empty array.
You can use unshift and shift to add and remove values from the
beginning of an array.
@a = (1,2,3);
$new = 6;
unshift(@a,$new); # same as @a = ($new, @a)
# so far: (6,1,2,3)
$old = shift(@a); # removes first element of @a
# so far: (1,2,3)
unshift(@a,4,5,6); # can unshift multiple values
# same as @a = (4,5,6,@a)
# so far: (4,5,6,1,2,3)
shift returns undef if given an empty array.
use strict;
my @stack;
push(@stack, 7, 6, "go");
# @stack is now qw/7 6 go/
my $action = pop @stack;
# $action is "go", @stack is (7, 6)
my $value = pop(@stack) + pop(@stack);
# value is 6 + 7 = 13, @stack is empty
use strict;
my @queue;
unshift (@queue, "Customer 1");
# @queue is now ("Customer 1")
unshift (@queue, "Customer 2");
# @queue is now ("Customer 2" "Customer 1")
unshift (@queue, "Customer 3");
# @queue is now ("Customer 3" "Customer 2" "Customer 1")
my $item = pop(@queue);
# @queue is now ("Customer 3" "Customer 2")
The reverse function reverses the array, returning the resulting list:
@a = (1,2,3);
@b = reverse(@a); # @b=(3,2,1), @a unchanged
@b = reverse(1,2,3); # same thing
@b = reverse(@b); # @b=(1,2,3)
Arrays and array slices will be interpolated (printed) with spaces between the
elements:
@a = (1,2,"bill",3);
print @a; # prints 12bill3
print "a: @a\n"; # prints a: 1 2 bill 3
print "a1: @a[1,2]\n"; # prints a1: 2 bill
@ (at sign)
Refers to the entire array or
slice of an array (when used with [ ]).
$ (dollar sign)
Refers to one element of the array, used with []
The chomp function also works for array variables, removing any ending
newlines in each element :
@comp111 = (“unix\n”, “shell\n”, “perl\n”);
chomp(@comp111);
# @comp111 is now (“unix”, “shell”, “perl”)
Array chomp is especially useful when reading a file or input from a user.
<STDIN> in a list context will return all remaining lines up to the end of the
file, or until the user hits CTRL-D.
@lines = <STDIN>; # read input in a list context
chomp(@lines); # remove all trailing newlines
foreach $i (@some_list){
...
}
The following example prints the numbers in reverse order without changing
the array:
#!/usr/local/bin/perl5 -w
@a = (1,2,3,4,5);
foreach $i (reverse @a){
print "$i ";
}
print "\n"; # 5 4 3 2 1
If you omit the scalar variable in foreach, Perl will use $_ automatically:
$ cat print3
#!/usr/local/bin/perl5 -w
@a = (1,2,3,4,5);
foreach (reverse @a){
print;
}
print "\n"; # 54321
print (and other Perl functions) use $_ as the default variable, if nothing is
specified.
The scalar variable in foreach is an alias for each variable in the list,
not a copy. (Tricky!)
If you modify the scalar variable in foreach, the aliased element in
the list is also changed:
#!/usr/local/bin/perl5 -w
@a = (1,2,3,4);
foreach $b (@a){
$b *= 2;
}
print "@a\n"; #2468
splice ARRAY[,OFFSET][,LENGTH][,LIST]
Similar to substr( STRING, OFFSET[, LEN] [, REPLACEMENT]) for strings.
Removes the elements designated by OFFSET and LENGTH from an array, and
replaces them with the elements of LIST
splice ARRAY,OFFSET,LENGTH
Removes the elements designated by OFFSET and LENGTH
from an array
splice ARRAY,OFFSET
Removes all the elements from OFFSET onwards
splice ARRAY
Removes everything
push(@a,$x,$y) splice(@a,@a,0,$x,$y)
pop(@a) splice(@a,-1)
shift(@a) splice(@a,0,1)
unshift(@a,$x,$y) splice(@a,0,0,$x,$y)
$a[$i] = $y splice(@a,$i,1,$y)
$a = <STDIN>;
@a = <STDIN>;
Each element is one line, and includes the terminating newline (the last line
may or may not have a newline).
Typically, a program will read in one line at a time and process the line:
while($line = <STDIN>){
# process line
print "$line";
}
$ ./line1
Hi hello
Hi hello
test
test
[CTRL-d] $
@lines = <STDIN>;
# process lines
print "@lines";
$ ./line3
hi
test
[CTRL-d] hi
test
$
Perl has a shortcut for reading a value from <STDIN> into $_.
Whenever a condition consists solely of <STDIN>, Perl automatically copies
the line into $_.
while(<>){ $cat f1
print; 1
} $cat f2
./prg f1 f2 2
1
2
If you do not specify any filenames on the command line, <> reads from
standard input automatically.
while(<>) {
print;
}
$ perl 1.pl
Hi
hi
test
test
[CTRL-d] $
The print function takes a list of strings, and sends each to STDOUT,
without adding any characters between them.
Sometimes, you will need to add parentheses to print, especially when the
first argument starts with a left parentheses:
You may wish to have more control over your output than print provides.
The printf function takes a list of arguments, where the first argument is a
format control string, which defines how to print the remaining arguments
(like printf in C).
Format types:
strings %s
integer numbers %d
floating-point numbers %f
$s = "1234567890";
$n = 12345;
$real = 1234567.123;
printf “[%15s] [%5d] [%10.2f]\n", $s, $n, $real;
# [ 1234567890] [12345] [1234567.12]
This example prints $s in a 15-character field, then space, then $n as
a decimal integer in a 5-character field, then another space, then
$real as a floating-point value with 2 decimal places in a 10-
character field, and finally a newline.
A hash (or associative array) is like an array, where the index can be
any scalar value (not just small non-negative integers).
A hash index is called a key (keys must be unique).
The elements of a hash have no fixed order, unlike arrays.
The keys are used to lookup the values.
KEYS “bill” 16 “0 C”
To initialize hashes:
$ cat morehash
#!/usr/local/bin/perl5 -w
%bill = ( "Gates" => “rich", "Clinton" => "busy");
print "Hello $bill{'Gates'} Bill!\n";
$ ./morehash
Hello rich Bill!
You may use single quotes for specifying a key and values
Hash variable names begin with the percent sign (%) followed by the
usual variable name.
$bill{234.5} = 456.7;
...
$bill{234.5} += 3; # makes it 459.7
Referencing a hash element that does not exist returns the undef value.
You can access the hash as a whole if you need to initialize it or to copy it.
The hash unwinds as a list. Each pair in the list represents the key and its
value.
$bill{"Gates"} = "rich";
$bill{"Clinton"} = "busy";
$bill{234.5} = 456.7;
@billarray = %bill;
# @billarray: qw(Gates rich 234.5 456.7 Clinton busy)
%a = @billarray; # create %a like %bill
%a = %bill;
%b = qw(Gates rich Clinton busy 234.5 456.7);
# initialize %b like %bill from list values
You can construct a hash with keys and values swapped using the reverse
function:
%aback = reverse %a;
The keys(%hashname) function returns a list of all the keys currently in the
hash.
%bill = ( "Gates" => "rich", "Clinton" => "busy");
The keys function is often used in foreach loops to print or access the
elements one-by-one:
#!/usr/local/bin/perl5 -w
$bill{"Gates"} = “rich";
$bill{"Clinton"} = "busy";
$bill{234.5} = 456.7;
foreach $k (sort(keys(%bill))){ #Here sort sorts keys in ASCII ascending order
print "At $k we have $bill{$k}\n"; # Just like linux/shell sort command, which sorts
} # contents of a file in ASCII ascending order
You cannot print the entire hash like you can print arrays:
#!/usr/local/bin/perl5 -w
$bill{"Gates"} = "Bill";
$bill{"Clinton"} = "Bill";
$bill{234.5} = 456.7;
print "Bill hash: %bill\n"; #Bill hash: %bill
print %bill; #GatesBillClintonBill234.5456.7
$bill{"Gates"} = “rich";
$bill{"Clinton"} = "busy";
$bill{234.5} = 456.7;
delete $bill{"Gates"};
while(($k,$v) = each(%bill)){
print "At $k we have $v\n";
}
#!/usr/local/bin/perl5 -w
@b{"Gates","Clinton",234} = qw(rich busy 45);
@k = qw(Gates Clinton);
print "The values are: @b{@k}\n";
# The values are: rich busy
At 234 we have 67
At Gates we have rich
At Horner we have 111
At Clinton we have busy
$ cat p1
#!/usr/local/bin/perl5 -w
$argc = @ARGV;
print "parameter count $argc for $0 (PID: $$)\n";
print "parmamters: $ARGV[0] $ARGV[1]\n";
print "You are $ENV{USER} \n";
$ ./p1 a b
parameter count 2 for p1 (PID: 20489)
parmamters: a b
You are Arpit
Note: Label must follow directly after the arrows with no spaces between.
Output:
hi there
lo there
Wed Aug 29 04:07:32 PDT 2012
Output:
echo hi there
echo lo there
date
File Input/Output
Functions/subroutines
Regular expressions (Strength of PERL)