Perl Tutorial - Practical Extraction and Reporting Language (Perl)
Please leave a remark at the bottom of each page with your useful suggestion.
Table of Contents
- Perl Introduction
- Perl Program Startup
- Perl Regular Expressions
- Perl Array Program
- Perl Basic Program
- Perl Subroutine / Function Program
- Perl XML Program
- Perl String Program
- Perl Statement Program
- Perl Network Program
- Perl Hash Program
- Perl File Handling Program
- Perl Data Type Program
- Perl Database Program
- Perl Class Program
- Perl CGI Program
- Perl GUI Program
- Perl Report Program
Perl Report Program
Add page number to page header
format standardformat_top =
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
"Page $%"
Employees
First Name Last Name ID Extension
--------------------------------------------
.
format standardformat =
@<<<<<<<<<<<<@<<<<<<<<<<<<@<<<<<<<<@<<<<
$firstname $lastname $ID $extension
.
$text = "Here is the data you asked for...";
$firstname = "Cary";
$lastname = "Grant";
$ID = 1234;
$extension = x456;
Add _TOP to add the page header
format STDOUT_TOP =
Employees
First Name Last Name ID Extension
--------------------------------------------
.
format STDOUT =
@<<<<<<<<<<<<@<<<<<<<<<<<<@<<<<<<<<@<<<<
$firstname $lastname $ID $extension
.
$firstname = "Cary"; $lastname = "Grant";
$ID = 1234; $extension = x456;
write;
Align fields on a report?
#!/usr/local/bin/perl -w
while (<ARGV>)
{
chomp;
($number,$type,$name,$price,$desc) = split (/\|/);
write;
}
format STDOUT =
@>>> @|||||| @<<<<<<<<< @<<<<<<<<<<<<< $@####.##
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$.,$number,$type,$name,$price,$desc
.
Align left, right and center
$str = formline <<'EOD', right, center, left;
Here's some text justification...
----------------------------
@<<<<<<<<@|||||||@>>>>>>>>>>
EOD
print "$^A\n";
A program that uses a print format.
#!/usr/local/bin/perl
$~ = "MYFORMAT";
write;
format MYFORMAT =
Here is the text I want to display.
.
A program that uses a value field that does formatting.
#!/usr/local/bin/perl
$string = "Here\nis a line of\ntext.\n";
$~ = "OUTLINE";
write;
format OUTLINE =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<
$string
.
A simple format example
#!/usr/bin/perl
use warnings;
use strict;
my $greeting = 'Hello';
my $planet = 'world';
write();
$greeting = 'Greetings';
$planet = 'Mars';
write();
$greeting = 'Howdy';
$planet = 'Pluto';
write();
format STDOUT =
I would like to say @<<<<<<<<< @<<<<<<<!
$greeting, $planet
.
Assign $~ to format
format standardformat =
@||||||||||||||||||||||||||
$text
.
$text = "Hello!";
$~ = standardformat;
write;
Attach a footer to a report
#!/usr/local/bin/perl -w
use English;
$pageCount = 0;
$pageItemCount = 0;
$FORMAT_LINES_PER_PAGE = 20;
while (<ARGV>)
{
chomp;
($number,$type,$name,$price,$desc) = split (/\|/);
write;
$pageCount++;
$pageItemCount++;
if ($FORMAT_LINES_LEFT <= 3)
{
print "Item Count For This Page $pageItemCount\n";
$pageItemCount = 0;
$FORMAT_LINES_LEFT = 0;
}
}
print "Item Count For This Page $pageItemCount\n";
exit;
format STDOUT_TOP= Count Item # Item Type Item Name Price Description Page@>>>>>>
$FORMAT_PAGE_NUMBER
-----------------------------------------------------------------------
.
format STDOUT=
@>>>> @|||||| @<<<<<<<<< @<<<<<<<<<<<<< @####.##
^<<<<<<<<<<<<<<<<<<<<<<<<<
$pageCount,$number,$type,$name,$price,$desc
~^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
~^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
.
Attach a header to a report
#!/usr/local/bin/perl -w
while (<ARGV>)
{
chomp;
($number,$type,$name,$price,$desc) = split (/\|/);
write;
}
format STDOUT_TOP=
Count Item # Item Type Item Name Price Description
------------------------------------------------------------------------
format STDOUT=
@>>>> @|||||| @<<<<<<<<< @<<<<<<<<<<<<< $@####.##
^<<<<<<<<<<<<<<<<<<<<<<<<<
$.,$number,$type,$name,$price,$desc
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
.
Call write to output the format
format STDOUT =
@*
$text
@<<<<<<<<<<<<@<<<<<<<<<<<<@<<<<<<<<@<<<<
$firstname $lastname $ID $extension
.
$text = "First Line...";
$firstname = "Cary";
$lastname = "Grant";
$ID = 1234;
$extension = x456;
write;
Controlling pagination
The $= variable holds the number of lines allowed on a page.
When the line number exceeds this amount, write outputs a new page.
$= defaults to 60.
The $- variable counts down as each line gets output on a page.
When $- gets to 0, write outputs a new page.
You can set $- to 0 to force a page output on the next call to write.
Setting $- works only if you have a top-of-page format, e.g., FILEHANDLE_TOP.
The following table lists the variables relating to pages and formats.
Variable Usage
$= Number of lines on a page; defaults to 60.
$- Number of lines left on the page.
$% Current page number.
$~ Name of format, defaults to same name as file handle.
$^ Name of top-of-page format, defaults to _TOP added to file handle.
$^L String to output to advance page, defaults to formfeed character.
Define format and variables for the format
format STDOUT =
@<<<<<<<<<<<@>>>>>>>>>>>>>>>
$text1 $text2
.
$text1 = "Hello";
$text2 = "there!";
write; #Uses STDOUT by default.
Different types of fields
#!/usr/bin/perl
use warnings;
use strict;
my $name = 'Tom';
my $streetAddress = '12 Avenue';
my $town = 'Gate';
my $state = 'CA';
my $zip = '11111-1111';
write();
$name = 'Jack';
$streetAddress = '12 Street';
$town = 'newTon';
$state = 'AC';
$zip = '00000-0000';
write();
$name = 'Mary';
$streetAddress = 'One City';
$town = 'Small';
$state = 'AQ';
$zip = '01234-5678';
write();
format STDOUT =
@||||||||||||||||||||||||||
$name
@||||||||||||||||||||||||||
$streetAddress
@<<<<<<<<<<<, @< @>>>>>>>>>
$town, $state, $zip
.
Dynamic Report Writing
open(FH, "datebook") or die; # Open a file for reading
open(SORT, "|sort") or die; # Open a pipe to sort output
$field1="<" x 18; # Create format strings
$field2="<" x 12;
$field3="|" x 10;
$field4="#" x 6 . ".##";
# Create the format template
$format=qq(
format SORT=
\@$field1\@$field2\@$field3\@$field4
\$name, \$phone, \$birth, \$sal
.
);
eval $format;
while(<FH>){
($name,$phone,$address,$birth,$sal)=split(":");
($first, $last)=split(" ", $name);
$name=$last.", ". $first;
write SORT;
}
close(FH);
close(SORT);
Field Designator Symbols
Field Designator Purpose
@ Indicates the start of a field
@* Used for multiline fields
^ Used for filling fields
Field Display Symbols
Type of Field Symbol Type of Field Definition
< Left justified
> Right justified
| Centered
# Numeric
. Indicates placement of decimal point
^ fieldholder creates a filled paragraph
#!/bin/perl
$name="Jack";
print "What is your favorite? ";
$quote = <STDIN>;
format STDOUT=
Play: @<<<<<<<<<< Quotation: ^<<<<<<<<<<<<<<<<<<
$name, $quote
^<<<<<<<<<<<<<<<<<<
$quote
^<<<<<<<<<<<<<<<<<<
$quote
~ ^<<<<<<<<<<<<<<<<<<
$quote
.
write;
Force a new page to output.
#!/usr/bin/perl -w
format WORKORDER=
itemB: @<<<<<<<<<<<<<<<<<<<< itemC: @>>>>>>>>
$itemB, $itemC
itemA: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$itemA
Access: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$access
Deck: @<< Stardate: @########.#
$deck, $stardate
.
# Top-of-page format, displays page number.
format WORKORDER_TOP=
=Starfleet Work Orders= page @<<<
$%
.
open(WORKORDER, ">yourFile.txt" ) or die "Can't open yourFile.txt", $!;
select(WORKORDER);
$itemA = "itemA 1";
$itemB = "NO 1";
$itemC = "Urgent";
$access = "NO";
$deck = 17;
$stardate = 200111.4;
write WORKORDER;
# Output page on next write.
$- = 0;
# Set up more data for output.
$itemA = "itemA 2";
$itemB = "No 2";
$itemC = "Low";
$access = "YEs";
$deck = 12;
$stardate = 200102.5;
write WORKORDER;
# Output page.
$- = 0;
# Fill in more data.
$itemA = "itemA 3";
$itemB = "NO 3";
$itemC = "Low";
$access = "Yes";
$deck = 10;
$stardate = 201002.0;
write WORKORDER;
# Close file.
close(WORKORDER);
Format Field Types
Format Meaning
@<<<<< Left-justified field.
@>>>>> Right-justified field.
@||||| Centered field.
@####.## Numeric field with given decimal digits, right justified.
In each case, the number of special characters defines the number of spaces allotted for the field in the report.
Format the number
$pi = 3.1415926;
format STDOUT =
@.## @.#######
$pi $pi
.
write;
Limitations of the @* value field.
#!/usr/local/bin/perl
$string = "Here\nis a line of\ntext.\n";
$~ = "OUTLINE";
write;
format OUTLINE =
@*
$string
.
Multiline fields
#!/usr/bin/perl
use warnings;
use strict;
my $name = 'Tom';
my $letters = 'AAA';
my $phone = '(111)111-1111';
my $itemA = <<'DONE';
Line 1
Line 2.
DONE
write();
$name = 'Jack';
$letters = 'AAA';
$phone = '(222)222-2222';
$itemA = <<'DONE';
Line 3
Line 4
Line 5
DONE
write();
$name = 'Mary';
$letters = 'CCC';
$phone = '';
$itemA = 'my item.';
write();
format STDOUT =
Name: @<<<<<<<<<<<<<<<<<<< itemA: ^<<<<<<<<<<<<<<<<<<<<<
$name, $itemA
letters: @<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<
$letters, $itemA
phone: @|||||||||||| ^<<<<<<<<<<<<<<<<<<<<<<<<~
$phone, $itemA
~ ^<<<<<<<<<<<<<<<<<<<<<<<<
$itemA
~ ^<<<<<<<<<<<<<<<<<<<<<<<<
$itemA
~ ^<<<<<<<<<<<<<<<<<<<<<...
$itemA
.
Output along with the template
#!/bin/perl
$name="Tommy";
$age=25;
$salary=50000.00;
$now="03/14/97";
# Format Template
format STDOUT=
---------------------REPORT-------------------------
Name: @<<<<<< Age:@##Salary:@#####.## Date:@<<<<<<<<<<
$name, $age, $salary, $now
.
# End Template
write;
print "Thanks for coming. Bye.\n";
Passing one variable with ! inside to format
format STDOUT =
English: ^<<<<<
$text
German: ^<<<<<<<<<
$text
French: ^<<<<<<<<
$text
.
$text = "Hello!Guten Tag!Bonjour!";
Passing value to the format
format STDOUT =
@<<<<<<<<<<<@<<<<<<<<<<<<<<<
$text1 $text2
@<<<<<<<<<<<@<<<<<<<<<<<<<<<
$text3 $text4
.
$text1 = "Hello";
$text2 = "there!";
$text3 = "How're";
$text4 = "things?";
write;
Perl stores page number in the $% variable.
# Top-of-page format, displays page number.
format WORKORDER_TOP=
Starfleet Work Orders, page @<<<
$%
.
Prints a value-field character.
#!/usr/local/bin/perl
format SPECIAL =
This line contains the special character @.
"@"
.
$~ = "SPECIAL";
write;
Put a variable in the report header
#!/usr/local/bin/perl -w
use English;
while (<ARGV>)
{
chomp;
($number,$type,$name,$price,$desc) = split (/\|/);
write;
}
format STDOUT_TOP=
Count Item # Item Type Item Name Price Description Page @>>>>>>
$FORMAT_PAGE_NUMBER
------------------------------------------------------------------------------
.
format STDOUT=
@>>>> @|||||| @<<<<<<<<< @<<<<<<<<<<<<< $@####.##
^<<<<<<<<<<<<<<<<<<<<<<<<<
$.,$number,$type,$name,$price,$desc
~^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
~^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
.
Report field pictures
FIELD PICTURE DESCRIPTION
@<<<<< A left-justified, 6-character-wide field.
@>>>>>>>>>> A right-justified, 10-character-wide field.
@|||| A centered, 5-character-wide field.
@###.## A float field broken into 5 integer characters and 2 fractional characters.
^<<<<<<<<<<<<<< A left-justified, 15-character field.
Separate the variables with commas to put multiple data fields on the same line
#!/usr/bin/perl -w
format WORKORDER=
itemB: @<<<<<<<<<<<<<<<<<<<< itemC: @>>>>>>>>
$itemB, $itemC
itemA: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$itemA
Access: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$access
Deck: @<< Stardate: @########.#
$deck, $stardate
.
# Open file.
open(WORKORDER, ">yourFile.txt" ) or die "Can't open yourFile.txt", $!;
# Output record.
$itemA = "This is a itemA";
$itemB = "itemB";
$itemC = "Low";
$access = "no";
$deck = 17;
$stardate = 99999.4;
write WORKORDER;
# Output record.
$itemA = "This is the second";
$itemB = "itemB 2";
$itemC = "High";
$access = "Yes";
$deck = 12;
$stardate = 99999.5;
write WORKORDER;
# Output record.
$itemA = "This is the third.";
$itemB = "itemB 3";
$itemC = "medium";
$access = "Via Jefferies Tube";
$deck = 10;
$stardate = 95212.0;
write WORKORDER;
# Close file.
close(WORKORDER);
Sets the length and print format for a page.
#!/usr/local/bin/perl
open (OUTFILE, ">file1");
select (OUTFILE);
$~ = "WRITELINE";
$^ = "TOP_OF_PAGE";
$= = 60;
while ($line = <STDIN>) {
write;
}
close (OUTFILE);
format TOP_OF_PAGE =
- page @<
$%
.
format WRITELINE =
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$line
.
Split a long field over multiple lines
#!/usr/local/bin/perl -w
while (<ARGV>)
{
chomp;
($number,$type,$name,$price,$desc) = split (/\|/);
write;
}
format STDOUT =
@>>>> @|||||| @<<<<<<<<< @<<<<<<<<<<<<< $@####.##
^<<<<<<<<<<<<<<<<<<<<<<<<<
$,,$number,$type,$name,$price,$desc
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<
$desc
.
The format Statement Special Variables
English Code Description
$FORMAT_AUTOFLUSH $| Auto flush on/off flag
$FORMAT_FORMFEED $^L Character string to output before a new page (excluding the first page)
$FORMAT_LINE_BREAK_ CHARACTERS $: Format line break characters
$FORMAT_LINES_LEFT $- Number of lines left before this format page starts a new page
$FORMAT_LINES_PER_PAGE $= Number of lines per page
$FORMAT_NAME $~ Format name
$FORMAT_PAGE_NUMBER $% Current format page number
$FORMAT_TOP_NAME $^ Top-of-form name
Top-of-page formatting
#!/usr/bin/perl
use warnings;
use strict;
my $product = 'Product Name';
my $price = 99.00;
my $number = '111';
write();
$product = 'PC';
$price = 550.34521;
$number = '222222';
write();
$product = 'House';
$price = '5';
$number = '111111';
write();
format STDOUT_TOP =
Product Price ID Number
---------------- --------- ---------
.
format STDOUT =
@<<<<<<<<<<<<<<<<<<<< $@####.## @<<<<<<<<
$product, $price, $number
.
Top-of-the-Page Formatting
File:datafile
Tom:5:5:5/19/88
Jack:4:4:5/6/99
Peter:3:3:4/12/98
#!/bin/perl
open(DB, "datafile" ) || die "datafile: $!\n";
format STDOUT=
-----------------------
| EMPLOYEE INFORMATION |
-----------------------
Name: @<<<<<<<<<<<<
$name
-----------------------
Age: @##
$age
-----------------------
Salary: @#####.##
$salary
-----------------------
Date: @>>>>>>>>>>
$start
.
while(<DB>){
($name, $age, $salary, $start)=split(":");
write ;
}
Understanding Formats
A format defines how data will appear.
The format command defines a format.
The basic syntax follows:
format NAME = formatdata
The format definition ends with a single period on its own on a line.
The format data come in pairs of lines.
In each pair, the first line, called the picture line, lists how the data will look;
the second line, called the argument line, lists the global Perl variables that will hold the data.
When the report is generated, the data values get plugged into the picture lines.
For example,
format NAMES=
Last name : @<<<<<<<<<<<<<<<<<<<<
$lastname
First name: @<<<<<<<<<<<
$firstname
.
The @<<<<<<<<<<< format defines a left-justified data field.
The number of < characters defines how many spaces are allotted for the field. The lines with variables, $lastname and $firstname, aren't printed.
Only the lines that define the format are printed.
Uses the select function.
#!/usr/local/bin/perl
open (FILE1, ">file1");
$string = "this is a test";
select (FILE1);
&writeline;
select (STDOUT);
&writeline;
close (FILE1);
sub writeline {
$~ = "WRITELINE";
write;
}
format WRITELINE =
I am writing @<<<<< to my output files.
$string
.
Using format to save data to a file
#!/usr/bin/perl -w
# Usage:
# Perl format1.pl outputfile
# Set up format.
format NAMES=
Last name : @<<<<<<<<<<<<<<<<<<<<
$lastname
First name: @<<<<<<<<<<<
$firstname
.
# Note period alone on line above.
# Also note blank line before period.
open(NAMES, ">yourFile.txt" ) or die "Can't open yourFile.txt, $!";
$lastname = "AA";
$firstname = "BB";
write NAMES;
$lastname = "FF";
$firstname = "MVV";
write NAMES;
close(NAMES);
Using new line character
format STDOUT =
@*
$text
.
$text = "Here\nis\nthe\ntext.";
write;
Using value fields to print output.
#!/usr/local/bin/perl
while ($line = <STDIN>) {
$line =~ s/[^aeiou]//g;
@vowels = split(//, $line);
foreach $vowel (@vowels) {
$vowelcount{$vowel} += 1;
}
}
$~ = "VOWELFORMAT";
write;
format VOWELFORMAT =
-----------------------------------------------------------
Number of vowels found in text file:
a: @<<<<< e: @<<<<<
$vowelcount{"a"}, $vowelcount{"e"}
i: @<<<<< o: @<<<<<
$vowelcount{"i"}, $vowelcount{"o"}
u: @<<<<<
$vowelcount{"u"}
-----------------------------------------------------------
.
Valid value-field formats.
Field Value-field format
@<<< Left-justified output
@>>> Right-justified output
@||| Centered output
@##.## Fixed-precision numeric
@* Multiline text
Write a format to a file
format standardformat_top =
Employees
First Name Last Name ID Extension
--------------------------------------------
.
format standardformat =
@<<<<<<<<<<<<@<<<<<<<<<<<<@<<<<<<<<@<<<<
$firstname $lastname $ID $extension
.
$firstname = "B";
$lastname = "A";
$ID = 1234; $extension = x456;
open FILEHANDLE, ">report.frm" or die "Can't open file";
select FILEHANDLE;
select FILEHANDLE;
$~ = standardformat;
$^ = standardformat_top;
write;
close;
Writes a string using the multiline field format.
#!/usr/local/bin/perl
@input = <STDIN>;
$string = join("", @input);
$~ = "MULTILINE";
write;
format MULTILINE =
****** contents of the input file: ******
@*
$string
*****************************************
.
Writes out as many formatted lines of output as necessary.
#!/usr/local/bin/perl
@quotation = <STDIN>;
$quotation = join("", @quotation);
$~ = "QUOTATION";
write;
format QUOTATION =
Quotation for the day:
-----------------------------
~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
-----------------------------
.
Writes out multiple formatted lines of output.
#!/usr/local/bin/perl
@quotation = <STDIN>;
$quotation = join("", @quotation);
$~ = "QUOTATION";
write;
format QUOTATION =
Quotation for the day:
-----------------------------
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
-----------------------------
.
Writes out multiple formatted lines of output and suppresses blank lines.
#!/usr/local/bin/perl
@quotation = <STDIN>;
$quotation = join("", @quotation);
$~ = "QUOTATION";
write;
format QUOTATION =
Quotation for the day:
-----------------------------
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$quotation
-----------------------------
.