Introduction to Perl

  1. Download perl from http://www.perl.com/
  2. What is Perl?

    Perl, which stands for "Practical Extraction and Report Language", was written by Larry Wall. Its a great language for doing data manipulation tasks. Its fast, portable, and accessible.


    My favorite Perl quotes:

    1. "If you toss a bunch of monkeys into a roomful of typewriters, the chances of them accidentally producing the complete works of Shakespeare are effectively nil. The chances of them producing a working Perl program, however, are actually good."
      -Nicholas Petreley

    2. "If Python is executable pseudocode, then perl is executable line noise."

    3. "Perl, the only language that looks the same before and after RSA encryption." - Keith Bostic

  3. Running a Perl program

    To run a program, type your code into a text file like, "HellowWorld.pl" and then enter this command:

    perl HelloWorld.pl
    
  4. Some small programs to learn perl by example:
    1. HelloWorld.pl
    2. - Demonstrates,
      "#" is a comment,
      the "print" statement,
      "\n" is the linefeed character.
      #program HelloWorld.pl
      print "Hello World!\n";
      
    3. HelloWorld2.pl
    4. - Demonstrates:
      declaring a string variable on the fly
      printing a variable
      #program HelloWorld2.pl
      $name = "Sarah";
      print "Hello $name!\n";
      
    5. HelloWorld3.pl
    6. - Demonstrates:
      Interactively reading a string from the user
      the chomp() function
      #program HelloWorld3.pl
      # this demonstrates how to read from the user and use the chomp() function
      print "What is your name?";
      $name = <STDIN>;
      chomp($name);   # get rid of the carriage return
      print "Hello $name!\n";
      
    7. HelloWorld4.pl
    8. - Demonstrates:
      the equal operator, "eq", for strings
      if-else clause
      #program HelloWorld4.pl
      # this demonstrates the equal operator, "eq", for strings and if-else clause
         print "What is your name?";
         $name = <STDIN>;
         chomp($name);   # get rid of the carriage return
         if($name eq "Tex")
            {
             print "Howdy $name!\n";
            }
         else
            {
             print "Hello $name!\n";
            }
      
    9. PrintArgs.pl
    10. - Demonstrates:
      The for loop
      Reading arguments from the command line
      Using the standard argument array, @ARGV, which is all the arguments passed in on the command line
      #program PrintArgs.pl
      # to print all the arguments passed:
           $numberOfArgs = @ARGV;
           print "The number of arguments passed was $numberOfArgs \n";
           for($i=0;$i < $numberOfArgs ; $i++)
           {
               print "argv[$i] = $ARGV[$i]\n";
           }
      

      Another form of the for loop doesn't use a counter

      #program ForLoop.pl
      # prints all the arguments passed in on the command line
      print "The argument elements passed in were: \n";
      for my $element ( @ARGV )
      {
          print "$element\n";
      }
      
    11. cat.pl
    12. - Demonstrates:
      Reading from a file
      #program cat.pl, a tiny program to print a file.
      open(MYFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      while($line = <MYFILE>)
      {
          print "${line}";
      }
      close(MYFILE);
      
      
      
    13. WriteToFile.pl
    14. - Demonstrates:
      Writing to a file
      #program WriteToFile.pl, a tiny program to write stuff to a file.
      # "OUTFILE" is the name of the file handle
      open(OUTFILE,">test.dat") || die "Cannot open file \"test.dat\"";
      for($i=0; $i < 10; $i++)
      {
          print OUTFILE " line $i\n";
      }
      close(OUTFILE);
      print "Finished writing to \"test.dat\"";
      
    15. paste.pl
    16. - Demonstrates:
      Checking for the right number of arguments
      Opening multiple files
      exit statement
      #program  paste.pl, a tiny program to paste the lines of one file onto another.
      # ie, append to line1 of file1 with line1 of file2
      if( @ARGV < 2) # is less than two arguments
         {    
            print "usage: paste.pl filename1 filename2";    exit 0;
         }
      # "FIRSTFILE" is the name of the file handle
      open(FIRSTFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      open(SECONDFILE,$ARGV[1]) || die "Cannot open file \"$ARGV[1]\"";
      while($line1 = <FIRSTFILE>)
      {
          $line2 = <SECONDFILE>;
          chomp($line1);  # removes the CR/LineFeed at the end
          print "${line1}${line2}";
      }
      close(FIRSTFILE);
      close(SECONDFILE);
      
    17. cut.pl
    18. - Demonstrates:
      Merging contents of files
      #program  cut.pl, a tiny program to print only certain columns of a file
      if( @ARGV < 3)
      {    
          print "usage: cut.pl filename StartColumn Length";    exit 0;
      }
      $StartColumn = $ARGV[1];  #needs more error checking here...
      $Length = $ARGV[2];
      open(MYFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      while($line = <MYFILE>)
      {
          print substr($line,$StartColumn-1,$Length)."\n";
      }
      
    19. List of variable type prefixes
      Variable Type Character Prefix
      Scaler $
      Array @
      Hash %
      Subroutine &
    20. List of special characters
      Character Meaning
      \n newline
      \" double quote
      \r carriage Return
      \t tab
    21. the substitution operator

      The 'g' means 'global', all instances on the line

      s/OldString/NewString/g
      or to do case insensitive use the 'i' modifier:
      s/OldString/NewString/ig
    22. ReplaceString.pl using the substitution operator, s/OldString/NewString/g

      #program  ReplaceString.pl
      if( @ARGV < 2)
      {    
          print "usage: ReplaceString.pl filename OldString NewString\n";
          print "   example: perl ReplaceString.pl intelliquest.txt ";
          print "IntelliQuest Kantar > kantar.txt\n";
          exit 0;
      }
      $OldString = $ARGV[1];
      $NewString = $ARGV[2];
      open(MYFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      while($line = &lt;MYFILE&gt;)
      {
          $line =~ s/$OldString/$NewString/g; # the "g" means "global", all
                                              #instances on the line
          print STDOUT $line;
      }
      
    23. Replace all strings in a file from the command line

      Just remember p i e

      perl -p -i -e 's/oldstring/newstring/g' textfile.txt
      
    24. Search.pl
    25. - Demonstrates:
      the matching operator, =~
      the index() function to find substrings in strings

      #program  Search.pl, example of the matching operator, =~
      if( @ARGV < 2)
      {    
          print "usage: Search.pl filename SearchString\n";
          print "   example: Search.pl iq.txt the \n";
          exit 0;
      }
      $SearchString = $ARGV[1];  #needs more error checking here...
      open(MYFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      $i=1;
      while($line = <MYFILE>)
      {
          if( $line =~ /$SearchString/i ) #does $line contain $SearchString?
                                          # /i means to ignore case
          {
        print STDOUT "$i: $line";
              $StartColumn = index($line,$SearchString)+1;
        print "  (\"$SearchString\" starts in column $StartColumn)\n";
          }
          $i++;
      }
      
    26. ColumnSearch.pl
    27. - Demonstrates:

      #program  ColumnSearch.pl, shows a string only if in certain columns
      if( @ARGV < 4)
      {    
          print "usage: ColumnSearch.pl filename SearchString StartColumn EndColumn\n";
          print "   example: ColumnSearch.pl sample.pst 6 20 20\n";
          exit 0;
      }
      $SearchString = $ARGV[1]; 
      $StartColumn = $ARGV[2]; 
      $EndColumn = $ARGV[3];
      $Length =  $EndColumn - $StartColumn + 1;
      open(MYFILE,$ARGV[0]) || die "Cannot open file \"$ARGV[0]\"";
      $i=1;
      while($line = <MYFILE>)
      {
          if( substr($line,$StartColumn-1,$Length) =~ /$SearchString/ ) 
          {
        print STDOUT "$i: $line";
          }
          $i++;
      }
      
    28. DBConnection.pl
    29. - Demonstrates:
      using the "|" operator to pipe output from a system command to a "psuedo-file".

      #DBConnection.pl
      # reads a database using isql on NT with SQLServer and returns info from pubs
      # 1999/08/21, mitch fincher
       MAIN:
       {
      $SelectStatement = "SELECT au_lname,au_fname,phone FROM authors ";
      $DBInfo =  "-H mfincher -S mfincher -d pubs";
      $SQLCommand = "isql -Uguest -P\"\" $DBInfo -h-1 -s! -w5000 -Q\" set nocount on $SelectStatement \"";
      print $SQLCommand;
      open(RESULTSET, $SQLCommand ." | ") || die "cannot do a sql statement";
       $i=1;
           while($line = <RESULTSET>)
           {
         chomp($line);
         $i++;
         ($au_lname,$au_fname,$phone) = split (/\!/,$line);
         $au_fname =~ s/ //g;
         $au_lname =~ s/ //g;
         $phone =~ s/[ ]*$//g; # remove only trailing blanks
      
         print "$au_fname $au_lname\'s phone number is $phone\n";
           }
          close(RESULTSET);
      }
      
      
  5. File Handling
    1. open a file for writing:
         open(OUTFILE, ">temp.out") || die "Cannot find temp.out";
         print OUTFILE "the time has come, the walrus said,...\n";
         close OUTFILE;
      
    2. open a file for appending:
      open(APPENDFILE, ">> $filename")
                        or die "Couldn't open $filename for appending: $!";
      
    3. open a file for reading:
      open(INFILE, "< $filename")
                        or die "Couldn't open $filename for reading: $!";
      
    4. read a whole file into an array and remove the linefeed (v5.0):
      chomp(@records = <FH>);
      
    5. File test operators
      Operator Meaning
      -e $file File exists
      -r $file File is readable
      -w $file File is writable
      -d $file File is a directory
      -f $file File is a file
      Example:
           if( -f "c:/autoexec.bat")
           {
           print "file exists\n";
           }
      
  6. Control Structures:
    1. for loop
           for ($i=1; $i<10;$i++)
              { print "$i\n"; } 
      
    2. While loop
            $j=1;
            while($j < 10)
               {
               print "$j ";
               $j++;
               }
      
    3. If-elsif-else
      $i=0;
      if ( $i eq 0 )
           { print "$i = 0"; }
      elsif ( $i eq 2 )
           { print "$i = 2"; }
      else 
           { print "$i != 2, $i !=0"; }
      
      
    4. foreach loop
          @names = ("Sarah", "Pam", "Mitch");
          foreach $name (@names)
             { print "$name, "; }
      
  7. Array Functions
    1. push - pushes an element onto the end of an array
      push (@myarray,$lastvalue) is the same as @myarray = (@myarray,$lastvalue)
    2. pop - pops the last value from an array. $value = pop(@myarray)
    3. unshift - pushes an element onto the front of an array
    4. shift - pops an element from the front of an array
    5. reverse - reverses the elements of an array
    6. sort - sorts array elements based on ascii values
    7. chomp - removes last record separator from each element
  8. Assign initial values to an array:
        @months = ("January","February","March","April","May","June",
             "July","August","September","October","November","December");
    or sans the quotes,
        @months = qw(January February March April May June 
                  July August September October November December);
    
    to use a specific element prepend it with a "$", like $months[$i].
    
    
    
    
  9. misc
         $dir = `dir *.pl`;  print $dir  // backtick operator
    
    perl -e 'srand; print int(rand(100))'  //kinda random generator
    perl -pi.bak -e "s/OLDSTRING/NEWSTRING/g" filelist  // substitues string in files.
     
    # to print a header to a web browser
       print "Content-type: text/html\n\n
    
    print STDOUT "Enter some text:"
    $mytext = <STDIN>;
    
    rename oldfilename newfilename
         renames file, 1 for success, 0 otherwise
    
    to get file info:
    stat filehandle
    example:
    
    @filestuff = stat "C:/autoexec.bat";
    print "filesize=".@filestuff[7];
    
    # how to show the current date?
    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    ++$mon; # that wierd month start at zero thingy
    print "$mon / $mday / $year";
    
        ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
        @months = ("January","February","March","April","May","June",
                 "July","August","September","October","November","December");
        $myDate = "@{months[${mon}]} ${mday}, ${year}";
    
    
    to access command line arguments:
    $ARGV[0] is the first arg (it skips the program name)
    $ARGV[1] is the second arg 
    $#ARGV is the count of arguments minus 1
    
    Check for an argument
    if(@ARGV < 3)
    {
        print "usage: programname yada yada yada";
        exit 0;
    }
    
    
    to create an array from parsing a string for separator tokens use "split"
    Example to parse the first input string for ~:
         @titleArray = split /~/,$ARGV[0];
    
    to get the length of an array:
         $len = scalar(@titleArray);
    or more simply,
         $len = @titleArray;
    
         
    to convert a string to lower case
    
    mystring =~ tr/A-Z/a-z/; #kinda like the unix tr command
    
    boolean tests: 
         == != > <   : tests for numerics
         eq ne lt gt : string
         
    
    
    to create a new directory
     mkdir("mydir", 0755) || die "Cannot create directory mydir: $!";
    
    
    print <<'ENDOFTEXT';
    any sort
    of text typed
    here will be printed.
    ENDOFTEXT
    
  10. Subroutine to print a file to stdout
    sub print_file 
    {
        local ($myfile) = @_;
    
        open(WORDSLIST, $myfile);
      while ($name = <WORDSLIST>) {
          print "$name";
      }
      close(WORDSLIST);
    }
    
  11. Invoke a perl script from a perl script on windows.

    Remember to put the complete path to perl.exe in front of your perl script.

        result = system("C:\\Perl\\bin\\perl.exe ReplaceString.pl \"USESAMPLEMGMT=1\" \"USESAMPLEMGMT=0\" $surveyName\\$surveyName.ini");
        result /= 256;
    
    
  12. Code fragment to change eol char to '<th>', read a line and put the characters between <th> into an array. This assumes one line in the input file.
        $/ = '<th>';
        $i = 0;
        while(<HEADERFILE>)
        {
      ~s/\<\/?t.\>//g;
      print $_."\n";
      if ($_ ne "")
          { 
        @fields[$i] = $_ ;
        ++$i;
          }
        }
        close(HEADERFILE);
        $/ = "\n";
    </pre>
    
    
    
    
    
  13. CGI.pl
    #!/usr/bin/perl
        use CGI qw(:standard);
    MAIN:
    {
        $query = new CGI;
        $| = 1;
        print $query->header('text/plain');
        $Name = $query->param('Name');
    
        print "Hello $Name";
    }
    
  14. Print the arguments passed in using cgi-lib
    #!/usr/bin/perl
    # this program just prints the name-value pairs passed to it from a form
    # mitch fincher 2000/07
    MAIN:
    {
         require "./cgi-lib.pl" || die "Cannot find cgi-lib.pl: $!";
         local(*in,$message,$command);
         &ReadParse(*in);
         print &PrintHeader;
    
         print "&lt;html&gt;\n&lt;head&gt;&lt;title&gt;Results&lt;/title&gt;&lt;/head&gt;\n";
         print "&lt;body&gt;\n";
         print "&lt;h1&gt;Submission From SimpleForm&lt;/h1&gt;\n";
         print "&lt;h2&gt;Variables passed in:&lt;/h2&gt;\n";
    
        while ( ($key, $value) = each %in) {
            print "$key = $value&lt;br &gt;\n";
        }
         print "&lt;/body&gt;&lt;/html&gt;";
    }
    
    
  15. Print the environmental variables using cgi-lib
    #!/usr/bin/perl
    # this program just prints the environmental variables available to a CGI
    # mitch fincher 2000/07
    MAIN:
    {
         require "./cgi-lib.pl" || die "Cannot find cgi-lib.pl: $!";
         local(*in);
         &ReadParse(*in);
         print &PrintHeader;
    
         print "&lt;html&gt;\n&lt;head&gt;&lt;title&gt;Environmental Variables&lt;/title&gt;&lt;/head&gt;\n";
         print "&lt;body&gt;\n";
         print "&lt;h1&gt;Environmental Variables&lt;/h1&gt;\n";
         print "&lt;h2&gt;Variables:&lt;/h2&gt;\n";
    
        while ( ($key, $value) = each %ENV) {
            print "$key = $value&lt;br &gt;\n";
        }
         print "&lt;/body&gt;&lt;/html&gt;";
    }
    
    
  16. A simple search engine using cgi-lib
    #!/usr/bin/perl
    # really basic server side search engine for finding one string of text
    #   for all the files of a certain extention in one directory.
    # This file is a basis for developing a better solution.
    # (I'm not proud of this solution, but its a first step).
    # For use on windows based system using the "find" command.
    # by mitch(at)fincher.org
    
    MAIN:
    {
        require "./cgi-lib.pl" || die "Cannot find cgi-lib.pl: $!";
        local(*in);
        print &PrintHeader;
        &ReadParse(*in);
    
        $STRING = $in{searchstring};
    # this is the type of files to search
        $FILES2SEARCH = "*.html";
    # this is the directory to search
        $DIR2SEARCH = "D:\\inetpub\\users\\mfincher";
        print "Searching Files for \"$STRING\" ...\n&lt;hr /&gt;";
        $command = "find /I \"$STRING\" $DIR2SEARCH\\$FILES2SEARCH";
        open(F, $command ." | ") || die "error";
        $filename = "";
        while (&lt;F&gt;) {
      chomp;
      if( /^---/ ) { # we hit a filename line, they start with "---"
          $firstone = 1;
          $filename = $_;
          $filename =~ s/.*\\//g;
          $filename =~ s/;//g;
      } elsif( length($_) &lt; 1) { # we hit a blank line
      } else {
          if($firstone == 1) { #is this the first from this file?
        print "match in file &lt;a href=\"$filename\"&gt;$filename&lt;/a&gt;:";
          }
          print "  &lt;xmp&gt; $_&lt;/xmp&gt;"; #print the line
          $firstone = 0;
      $i++;
      }
        }
        close(F);
        
        print "\n&lt;hr&gt;search complete.&lt;br&gt;\n";
        
        
        if ( $i == 0 )
        { print "Sorry, no matches found for \"$STRING\".\n"; }
        else
        { print "$i matches found for \"$STRING\"\n"; }
        
    }
    
  17. Use atoi to convert ascii strings to integers

        $thisyear = ${year}.atoi + 1900;
    
  18. How to read arguments to a subroutine

    A special array is created containing all the arguments called "@_". Use $_[n] to access the arguments.

    CopyFile(thisFile, thatFile);
    ...
    sub CopyFile {
        $inFileName = $_[0];
        $outFileName = $_[1];
        print "\r\n    inFileName = $inFileName";
        print "\r\n    outFileName = $outFileName";
    ...
    }
    
    
    
  19. Show elapsed time

    my $starttime=time();
    #do interesting stuff here...
    printf "\nElapsed Time: %d seconds\n",time()-$starttime;
    
    
  20. To view the load directories

    perl -e 'print "@INC \n";'
    

A good cheat sheet is at www.pcwdld.com/perl-cheat-sheet.