110 likes | 210 Views
CSC 352– Unix Programming, Fall 2012. Weeks 13 & 14, 2012 Perl Programming (Highlights only), Chapter 15. Project 5. Project 5 is a redo of Project 3 in Perl. ~parson/unix/perl5.zip has the handout code. perl5/diffcheck is the assignment 3 difference checker as a Bash script.
E N D
CSC 352– Unix Programming, Fall 2012 Weeks 13 & 14, 2012 Perl Programming (Highlights only), Chapter 15
Project 5 • Project 5 is a redo of Project 3 in Perl. • ~parson/unix/perl5.zip has the handout code. • perl5/diffcheck is the assignment 3 difference checker as a Bash script. • perl5/diffcheck.pl is the assignment 5 difference checker as a Perl script. • Use diffcheck and diffcheck.pl as a Rosetta Stone. It shows you Bash scripting constructs and their Perl counterparts. • perl5/replacestr is my assignment 3 solution as a Bash script. • perl5/replacestr.pl is your starting point for a Perl script.
diffcheck.pl part 1 • $USAGE="USAGE: diffcheck.pl DIRNAME1 DIRNAME2"; • Perl assignments use a $ for defining and using any Perl variable. • Perl terminates each command with a semicolon. • Do not leave spaces around the = operator.
diffcheck.pl part 2 if ($#ARGV != 1) { print STDERR "$USAGE\n"; print "NUMARGS $#ARGV\n"; exit 1; } • $#ARGV is the index of the final command-line argument; it is one less than Shell’s $#. • if, while, and foreach programming control constructs require { curly braces } around their code blocks, just like C++. • Use print, not echo as in Shell. Put double quotes around the string, and redirect to STDERR if needed. Note the \n.
diffcheck.pl part 3 $DIR1=shift; $DIR2=shift; if (! (-d $DIR1)) { print STDERR "ERROR. $DIR1 is not a valid directory.\n"; exit 1; } • shift returns the next command line argument and shifts it away (discards it). • -d tests for a directory. See Table 15.2 in the text. <, <=, ==, >=, > and != are for numeric comparison. lt, le, eq, ge, gt and ne are for string comparison. This is the opposite of the Shell!
diffcheck.pl part 4 $STARTDIR=`pwd`; # note the starting directory chomp($STARTDIR); # Get rid of any trailing (\n). • Using backticks runs a command via the Shell. • The returned result includes the trailing newline char (\n). • Use chomp to strip that \n out of the returned string. • foreach $file (`find . -type f -print`) { • The foreach command loops over every element in an array. • A backticked Shell command that returns multiple lines actually returns a Perl array, instead of a Shell-like string. • Always use chomp on anything returned via backticks.
diffcheck.pl part 5 foreach $file (`find . -type f -print`) { chomp($file); # strip away leading & trailing white space in file name print "DIFF $file ../$DIR2/$file\n"; system("diff $file ../$DIR2/$file 2>&1"); } • Note use of chomp on each string returned from a backticked Shell command. • system() function runs its string in the Shell without returning a value.
While loop from my replacestr.pl while ($#ARGV > 0) { • This really says, “while the number of command line arguments is > 1”. • $#ARGV is the index of the last element in the command line array, where the array starts at element 0. When $#ARGV == 0, there is in fact 1 element in the command line array. • Use something like $myvar=shift; to read the next command line argument into your variable called $myvar and to shift it out of the command line array. This shift decrements $#ARGV. • The while loop uses curly brace delimiters, just like the if and foreach programming constructs; if also supports else and elsif, see Figure 15.2 in the textbook.
Handout replacestr.pl foreach $file (`find $DIRNAME -type f -print | xargs grep -l "$PAT"`) { chomp($file); • Because the backticks return an array of strings, we will combine the find and the grep in a single backtick to the Shell. • The xargs command takes the stdout of the previous command in the pipeline and plugs those strings in as command line arguments for the command that xargs runs. • In this case find supplies a list of regular files to xargs, which plugs them in as command line arguments for grep. • Otherwise, we would have to join the array as shown on the next page.
You won’t need to do this: @allarray=`find $DIRNAME -type f -print`; Get all regular file paths into array @allarray. chomp(@allarray); Discard the \n on every element in the array. $all=join(" ", @allarray); Join the file paths into a single, space-separated string. @matchesarray=`grep -l "$PAT" $all`; Find matching files using grep –l, save into @matchesarray. foreach $file (@matchesarray) { Within loop chomp($file); and do other replacestr.pl steps.
Assignment 5 • Assignment 5 is due by the end of Saturday, December 8 via gmake turnitin. There is another handout for the assignment. • The comments in replacestr.pl outline your code, just like replacestr in assignment 3. • You have my Shell file replacestr in this assignment handout. • You need to use Perl syntax, control constructs, and command line argument processing. • Use backticks to run Shell command lines similar to the solution in replacestr.