Showing posts with label Perl. Show all posts
Showing posts with label Perl. Show all posts

Thursday, November 10, 2011

Famous Perl One-Liners Explained

— SkyHi @ Thursday, November 10, 2011

Here is the general plan:
REFERENCES

Tuesday, November 9, 2010

Counting the occurrences of a substring - the fastest way

— SkyHi @ Tuesday, November 09, 2010
So what is the fastest way to count how often a substring occurs inside a string, e.g. how many dashes can be found in “1-4-7-8-37-5-7-8-3-42″? I identified five ways to make Perl say “9″ to this challenge:

   1. my $size = (scalar(@{[$string =~ /-/g]}) + 1);
   2. my $size = scalar(split /-/, $string);
   3. my $size = (($string =~ s/-//g) + 1);
   4. my $size = (($string =~ tr/-//) + 1);
   5. my $size = 1; $size++ while $string =~ /-/g;

I would have assumed that number 1 would be the fastest way as it requires no modifcation of the string. A quick run with “cmpthese” from the Benchmark module revealed that my assumption was wrong:

Rate            match (1)       split (2)     while (5)     repl (3)     tr (4)
match (1)    51106/s          –               -90%         -93%      -94%        -95%
split (2)       495540/s        870%         –              -36%       -45%       -47%
while (5)     771605/s        1410%       56%          –            -15%        -18%
repl (3)       908265/s        1677%       83%       18%           –               -4%
tr (4)          941620/s         1742%        90%      22%          4%                –

The table shows a clear advantage when counting the occurrences via a while-loop (solution 5), count the replaced characters (solution 3) or truncating all occurrences (solution 4). While “tr” was the fastest way during this test run, it wasn’t the best way on other benchmark runs or others systems. If you want to try it yourself you can do so with the attached test-script.

Cluebringer tracking.pm :
my $p = '\<(.*?)\>';
#my $totalrecipient =0;
#$totalrecipient++ while DBQuote($sessionData->{'RecipientData'}) =~ /$p/g;
my $totalrecipient = (scalar(@{[DBQuote($sessionData->{'RecipientData'}) =~ /$p/g]}));


REFERENCES
http://www.chengfu.net/2005/10/count-occurrences-perl/

Saturday, November 6, 2010

PHP perl Extract Email Addresses

— SkyHi @ Saturday, November 06, 2010
f you need to extract email addresses from a plain text database or other plain text file, the software in this article can do it for you.

A plain text file is a file that contains only regular keyboard characters. (Even if the file contains a bunch of non-keyboard characters, the email address extractor software can still extract email addresses from the plain text parts of the file.)

Perhaps you need a list of all those who have purchased Ebook Title One to let them know it has been updated and where they can pick up the latest version. Perhaps something is coming up in your life and you need to send an email to all your regular correspondents.

Whatever the reason, if the email addresses are in a plain text file, they can be extracted. Even if the addresses are scattered among other text in the file.

If the data is in a CSV file, simply process the entire file with the email address extractor. The same with files containing tab- or other character delimited fields.

Addresses can be extracted from any plain text file that has email addresses within its content.

For a MySQL database with email addresses in columns containing other text, export the data to a CSV file. Then, process the exported data file with the email address extractor.

If you use Thunderbird or Apple's Mail or other email software that maintains emails in plain text databases, addresses can be extracted from the emails. Drag a copy of the emails to to be scanned into a separate folder. The the plain text file on your hard drive that contains the emails for that folder can be processed with the email address extractor.

The extracted email addresses can be used in PDQ Mailer (a WebSite's Secret exclusive), B-Mailer, or any other emailer that lets you import a list of email addresses.

Here is the source code of the software to extract email addresses. No customization necessary. Copy it, save it in a plain text processor as EmailExtract.php, and upload it to your server.
<html>
<head>
<style type="text/css">
body { font-family:sans-serif; margin:50px 0 50px 200px; }
input, textarea, #content { width:500px; }
.check { width:20px; }
a { text-decoration:none; }
</style>
<head>
<body>
<div id="content">
<div style="float:right;">
<a href="http://www.willmaster.com/">
<img src="http://www.willmaster.com/images/wmlogo_icon.gif" 
border="0" width="50" height="50" alt="Willmaster.com logo" 
title="Making quality web site software for over a decade.">
</a>
</div>
<h3>Email Address Extraction Software</h3>
<?php
$Emails = array();
$Continue = true;
$Domain = preg_replace('/:\d+$/','',$_SERVER['HTTP_HOST']);
function ExtractAddys($s)
{
   global $Emails;
   preg_match_all('/([a-zA-Z0-9-_\.]+@[a-zA-Z0-9-_\.]+)/',$s,$matched);
   foreach( $matched[1] as $addy ) { @$Emails{strtolower($addy)}++; }
}
if( count($_POST) )
{
   $_POST['file'] = trim($_POST['file']);
   $typeOfFile = 'pasted into the text box';
   if( preg_match('/^http:\/\//i',$_POST['file']) and (!preg_match('/[\r\n]/',$_POST['file'])) )
   {
      $location = preg_replace('/^http:\/\//i','',$_POST['file']);
      $location = preg_replace('/^[^\/]+/','',$location);
      $location = urldecode($location);
      $fp = fopen($_SERVER['DOCUMENT_ROOT'].$location,'rt');
      if( $fp )
      {
         while( ! feof($fp) ) { ExtractAddys( fgets($fp,4096) ); }
         fclose($fp);
      }
      else
      {
         $Continue = false;
         echo '<h4>Unable to open file '.$location.'<br>(URL '.$_POST['file'].')</h4>';
      }
      $typeOfFile = 'in the file at URL '.$_POST['file'];
   }
   else { ExtractAddys($_POST['file']); }
   if( $Continue )
   {
      if( count($Emails) )
      {
         echo '<p>The email addresses extracted from text '.$typeOfFile.':</p>';
         if( (!empty($_POST['sort'])) and $_POST['sort'] == 'yes' ) { ksort($Emails); }
         $separator = "\n";
         $boxheight = 250;
         if( (!empty($_POST['comma'])) and $_POST['comma'] == 'yes' )
         {
            $separator = ',';
            $boxheight = 45;
         }
         $onlyone = ( (!empty($_POST['purge'])) and $_POST['purge'] == 'yes' ) ? true : false;
         echo '<form><textarea wrap="off" style="height:'.$boxheight.'px;">';
         foreach( $Emails as $addy => $v )
         {
            echo "$addy$separator";
            if( $onlyone ) { continue; }
            for( $i=1; $i<$v; $i++ ) { echo "$addy$separator"; }
         }
         echo '</textarea></form>';
      }
      else {  echo '<p>No email addresses were extracted from text '.$typeOfFile.':</p>'; }
   }
   echo '<div style="margin:25px;"><hr width="50%"></div>';
}
?>

<p>
To extract email addresses from a plain text file, either
</p>
<ul>
<li>
paste the content of the file into the text box, or
</li>
<li>
upload the file to the <?php echo($Domain); ?> server and then type the file's URL into the text box.
</li>
</ul>
<form method="post" action="<?php echo($_SERVER['PHP_SELF']) ?>">
<textarea style="height:250px;" name="file"></textarea>
<p>
<input type="checkbox" class="check" name="comma" value="yes">Comma-separated on one line.<br>
<input type="checkbox" class="check" name="purge" value="yes">Purge duplicates.
<br>
<input type="checkbox" class="check" name="sort" value="yes">Sort.
</p>
<p>
<input type="submit" name="submit" value="Submit">
</p>
</form>
<p>
Copyright 2010 <a href="http://www.willmaster.com/">Bontrager Connection, LLC</a>
</p>
</div>
</body>
</html>


When EmailExtract.php is on your server, type its URL into your browser.

You'll see a text box where you can paste in the content of the plain text file that contains email addresses to extract.

If the plain text file is larger than 32k (which is the maximum form submission size for some browsers), the file can be uploaded to your server. Upload it to the same domain that EmailExtract.php is installed at. Then, instead of pasting the file into the text box, type or paste the uploaded file's http://... URL into it.

Unless modified, the software can not be used to extract email addresses from any URL except URLs of files located on the server where the software is installed. In other words, if you install the software on your domain and someone else guesses the URL, it can not be used to extract email addresses from web pages on other domains.

Installing the software is copy and paste. Using the software is copy and paste.

The extracted email addresses can be used with emailing software that lets you import your own list.


1. perl -wne'while(/[\w\.\-]+@[\w\.\-]+\w+/g){print "$&\n"}' emails.txt | sort -u > output.txt


Outlook Attachment Bounces
#
grep -C 2 "fatal errors" bounces.txt > step1.txt
#
perl -wne'while(/[\w\.\-]+@[\w\.\-]+\w+/g){print "$&\n"}' step1.txt | sort -u > step2.txt
#
sort step2.txt |uniq > step3.txt



REFERENCES
http://www.willmaster.com/library/email/extract-email-addresses.php
http://bytes.com/topic/unix/answers/648158-extract-email-addresses-big-file
http://www.getfreefile.com/mailhuntscreenshots.html

Tuesday, August 10, 2010

I never really understood: what is CGI?

— SkyHi @ Tuesday, August 10, 2010

CGI is a Comman Gateway Interface. As the name says, it is a "common" gateway interface for everything. It is so trivial and naive from the name. I feel that I understood this and I felt this every time I encountered this word. But frankly, I didn't. I'm still confused.



I am a PHP programmer. I did lot of web development.



user (client) request for page ---> webserver(->embedded PHP interpreter) ----> Server side(PHP) Script ---> MySQL Server.



Now say my PHP Script can fetch results from MySQL Server && MATLAB Server && Some other server.



So, now PHP Script is the CGI? because its interface for the between webserver & All other servers? I don't know. Sometimes they call CGI, a technology & othertimes they call CGI a program or someother server.



  • What exactly is CGI?

  • Whats the big deal with /cgi-bin/*.cgi? Whats up with this? I don't know what is this cgi-bin directory on the server for. I don't know why they have *.cgi extensions.

  • Why does Perl always comes in the way. CGI & Perl (language). I also don't know whats up with these two. Almost all the time I keep hearing these two in combination "CGI & Perl". This book is another great example CGI Programming with Perl Why not "CGI Programming with PHP/JSP/ASP". I never saw such things.

  • CGI Programming in C this confuses me a lot. in C?? Seriously?? I don't know what to say. I"m just confused. "in C"?? This changes everything. Program needs to be compiled and executed. This entirely changes my view of web programming. When do I compile? How does the program gets executed (because it will be a machine code, so it must execute as a independent process). How does it communicate with the web server? IPC? and interfacing with all the servers (in my example MATLAB & MySQL) using socket programming? I'm lost!!

  • They say that CGI is depreciated. Its no more in use. Is it so? What is its latest update?




Once, I ran into a situation where I
had to give HTTP PUT request access to
web server (Apache HTTPD). Its a long
back. So, as far as I remember this is
what I did:



  1. Edited the configuration file of Apache HTTPD to tell webserver to pass
    all HTTP PUT requests to some
    put.php ( I had to write this PHP
    script)

  2. Implement put.php to handle the request (save the file to the location
    mentioned)



People said that I wrote a CGI Script.
Seriously, I didn't have clue what
they were talking about.




  • Did I really write CGI Script?


I hope you understood what my confusion is. (Because I myself don't know where I'm confused). I request you guys to keep your answer as simple as possible. I really can't understand any fancy technical terminology. At least not in this case.



EDIT:



I found this amazing tutorial "CGI Programming Is Simple!" - CGI Tutorial Which explains the concepts in simplest possible way. After reading this article you may want to read Getting Started with CGI Programming in C to supplement your understanding with actual code samples. I've also added these links to this tutorial to Wikipedia's article : http://en.wikipedia.org/wiki/Common_Gateway_Interface



9 Answers

CGI is an interface which tells the webserver how to pass data back and forth to and from an application. More specifically, it describes how request information is passed in environment variables (such as request type, remote IP address), how the reqeust body is passed in via standard input, and how the response is passed out via standard output. You can refer to the CGI specification for details.



To use your image:



user (client) request for page ---> webserver ---[CGI]----> Server side Program ---> MySQL Server.



Most, if not all, webservers can be configured to execute a program as a 'CGI'. This means that the webserver, upon receiving a request, will forward the data to a specific program, setting some environment variables and marshalling the parameters via standard input and standard output so the program can know where and what to look for.



The main benefit is that you can run ANY executable code from the web, given that both the webserver and the program know how CGI works. That's why you could write web programs in C or Bash or Brainfuck with a regular CGI-enabled webserver. That, and that most programming environments can easily use standard input, standard output and environment variables.



In your case you most likely used another, specific for PHP, means of communication between your scripts and the webserver, this, as you well mention in your question, is an embedded interpreter called mod_php.



So, answering your questions:




What exactly is CGI?




See above.




Whats the big deal with /cgi-bin/*.cgi? Whats up with this? I don't know what is this cgi-bin directory on the server for. I don't know why they have *.cgi extensions.




That's the traditional place for cgi programs, many webservers come with this directory pre configured to execute all binaries there as CGI programs. The .cgi extension denotes an executable that is expected to work through the CGI.




Why does Perl always comes in the way. CGI & Perl (language). I also don't know whats up with these two. Almost all the time I keep hearing these two in combination "CGI & Perl". This book is another great example CGI Programming with Perl Why not "CGI Programming with PHP/JSP/ASP". I never saw such things.




Because Perl is ancient (older than PHP, JSP and ASP which all came to being when CGI was already old, Perl existed when CGI was new) and became fairly famous for being a very good language to serve dynamic webpages via the CGI. Nowadays there are other alternatives to run Perl in a webserver, mainly mod_perl.




CGI Programming in C this confuses me a lot. in C?? Seriously?? I don't know what to say. I"m just confused. "in C"?? This changes everything. Program needs to be compiled and executed. This entirely changes my view of web programming. When do I compile? How does the program gets executed (because it will be a machine code, so it must execute as a independent process). How does it communicate with the web server? IPC? and interfacing with all the servers (in my example MATLAB & MySQL) using socket programming? I'm lost!!




You compile the executable once, the webserver executes the program and passes the data in the request to the program and outputs the received response. CGI specifies that one program instance will be launched per each request. This is why CGI is inefficient and kind of obsolete nowadays.




They say that CGI is deprecated. Its no more in use. Is it so? What is its latest update?




CGI is still used when performance is not paramount and a simple means of executing code is required. It is inefficient for the previously stated reasons and there are more modern means of executing any program in a web enviroment. Currently the most famous is FastCGI.


REFERENCES
http://stackoverflow.com/questions/2089271/i-never-really-understood-what-is-cgi/2089297#2089297




Tuesday, July 27, 2010

FIND AND REPLACE with SED

— SkyHi @ Tuesday, July 27, 2010
FIND AND REPLACE with SED







Let us start off simple:

Imagine
you have a large file ( txt, php, html, anything ) and you want to
replace all the words "ugly" with "beautiful" because you just met your
old friend Sue again and she/he is coming over for a visit.





This is the command:













CODE
$
sed -i 's/ugly/beautiful/g'
/home/bruno/old-friends/sue.txt





Well, that command speaks for itself "sed" edits "-i in
place ( on the spot ) and replaces the word "ugly with "beautiful"
in the file "/home/bruno/old-friends/sue.txt"





Now, here comes the real magic:

Imagine
you have a whole lot of files in a directory ( all about Sue ) and you
want the same command to do all those files in one go because she/he is
standing right at the door . .

Remember the find command ? We will combine the two:













CODE
$
find /home/bruno/old-friends -type f
-exec sed -i 's/ugly/beautiful/g' {} \;





Sure
in combination with the find command you can do all kind of nice
tricks, even if you don't remember where the files are located !





Aditionally I did find a little script on the net for if you often have to find and
replace multiple files at once:













CODE
#!/bin/bash

     for fl in *.php; do

     mv $fl $fl.old

     sed 's/FINDSTRING/REPLACESTRING/g' $fl.old > $fl

     rm -f $fl.old

     done



just replace the "*.php", "FINDSTRING" and "REPLACESTRING"
make it executable and you are set.



I
changed a www address in 183 .html files in one go with this little
script . . . but note that you have to use "escape-signs" ( \ ) if
there are slashes in the text you want to replace, so as an example:
's/www.search.yahoo.com\/images/www.google.com\/linux/g' to change
www.search.yahoo.com/images to www.google.com/linux









For the lovers of perl I also found this one:













CODE
#
perl -e "s/old_string/new_string/g;"
-pi.save $(find DirectoryName -type f)



But
it leaves "traces", e.g it backs up the old file with a .save extension
. . . so is not really effective when Sue comes around ;-/







REFERENCE
http://www.brunolinux.com/02-The_Terminal/Find_and%20Replace_with_Sed.html

Tuesday, June 1, 2010

time stamp of file create

— SkyHi @ Tuesday, June 01, 2010
perl version for inodetime



Code:


<!--ntstart-->#!/usr/contrib/bin/<acronym title="Practical Extraction and Report Language">perl</acronym>
#^###################################################################
#^ $Header: inodetime.pl,v 1.1 97/01/20 10:17:00 http srvr? $
#^###################################################################
#^ PROGRAM DESCRIPTION
#^ -------------------
#^ This program prints the modification times and names of files.
#^ It uses the following format: inodetime.pl filename
#^ It will accept: inodetime.pl filename1 filename2 filename3
#^ inodetime.pl /tmp/file*
#^ The format of the output is: YYYYMMDDhhmmss filename
#^ example:
#^ $ inodetime.pl /tmp/t*
#^ 19961115105425 /tmp/test.sql
#^ 19970116113616 /tmp/tststat.pl
#^
#^ TRICK To Remember The Program Name
#^ ----------------------------------
#^ inodetime == I No De Time
#^ ^^ ^ ^
#^ KSG
#^###################################################################

############################################
# Get the (next) input from the command line
############################################
while ($curfile = $ARGV[0])
{
#################################################
# Do following code block only if $curfile exists
#################################################
if (-e $curfile)
{
###############################
# stat structure into variables
###############################
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat("$curfile");
###############################
# time structure into variables
###############################
local($sec,$min,$hr,$day,$mon,$yr,$wday,@dntcare) = localtime($mtime);
$yr = ($yr>=70) ? $yr+1900 : $yr+2000;
$yr="$yr";
$mon = (++$mon < 10) ? "0$mon" : "$mon";
$day = ($day < 10) ? "0$day" : "$day";
$hr = ($hr < 10) ? "0$hr" : "$hr";
$min = ($min < 10) ? "0$min" : "$min";
$sec = ($sec < 10) ? "0$sec" : "$sec";
##################################################################
# Rearrange in the YYYYMMDDhhmmss format and assign to $dte variable
##################################################################
$dte = join('',$yr,$mon,$day,$hr,$min,$sec);
######################################
# Print modification date and filename
######################################
print ("$dte $curfile\n");
}
########################################
# Shift to next position in command line
########################################
shift (@ARGV);
}


#~###################################################################
#~###################################################################
#~
#~ $Log: inodetime.pl,v $
#~ Revision 1.1 97/01/20 10:17:00 10:17:00 http ()
#~ reversed output
#~ from: filename date
#~ to: date filename
#~
#~ Revision 1.0 97/01/17 12:37:32 12:37:32 http ()
#~ Initial revision
#~
#~###################################################################
#~###################################################################



REFERENCES
http://www.unix.com/unix-dummies-questions-answers/14206-time-stamp-file-create.html

Monday, May 31, 2010

The top 10 tricks of Perl one-liners

— SkyHi @ Monday, May 31, 2010



I’m a recovering perl hacker. Perl used to be far and away my language of choice, but these days I’m more likely to write new code in Python, largely because far more of my friends and coworkers are comfortable with it.



I’ll never give up perl for quick one-liners on the command-line or in one-off scripts for munging text, though. Anything that lasts long enough to make it into git somewhere usually gets rewritten in Python, but nothing beats perl for interactive messing with text.



Perl, never afraid of obscure shorthands, has accrued an impressive number of features that help with this use case. I’d like to share some of my favorites that you might not have heard of.


One-liners primer


We’ll start with a brief refresher on the basics of perl one-liners before we begin. The core of any perl one-liner is the -e switch, which lets you pass a snippet of code on the command-line:

perl -e 'print "hi\n"' prints “hi” to the console.


The second standard trick to perl one-liners are the -n and -p flags. Both of these make perl put an implicit loop around your program, running it once for each line of input, with the line in the $_ variable. -p also adds an implicit print at the end of each iteration.


Both of these use perl’s special “ARGV” magic file handle internally. What this means is that if there are any files listed on the command-line after your -e, perl will loop over the contents of the files, one at a time. If there aren’t any, it will fall back to looping over standard input.



perl -ne 'print if /foo/' acts a lot like grep foo, and perl -pe 's/foo/bar/' replaces foo with bar



Most of the rest of these tricks assume you’re using either -n or -p, so I won’t mention it every time.


The top 10 one-liner tricks


Trick #1: -l


Smart newline processing. Normally, perl hands you entire lines, including a trailing newline. With -l, it will strip the trailing newline off of any lines read, and automatically add a newline to anything you print (including via -p).



Suppose I wanted to strip trailing whitespace from a file. I might naïvely try something like


  perl -pe 's/\s*$//'

The problem, however, is that the line ends with "\n", which is whitespace, and so that snippet will also remove all newlines from my file! -l solves the problem, by pulling off the newline before handing my script the line, and then tacking a new one on afterwards:


  perl -lpe 's/\s*$//'<br />


Trick #2: -0

Occasionally, it’s useful to run a script over an entire file, or over larger chunks at once. -0 makes -n and -p feed you chunks split on NULL bytes instead of newlines. This is often useful for, e.g. processing the output of find -print0. Furthermore, perl -0777 makes perl not do any splitting, and pass entire files to your script in $_.
  find . -name '*~' -print0 | perl -0ne unlink<br />

Could be used to delete all ~-files in a directory tree, without having to remember how xargs works.


Trick #3: -i

-i tells perl to operate on files in-place. If you use -n or -p with -i, and you pass perl filenames on the command-line, perl will run your script on those files, and then replace their contents with the output. -i optionally accepts an backup suffix as argument; Perl will write backup copies of edited files to names with that suffix added.
  perl -i.bak -ne 'print unless /^#/' script.sh<br />

Would strip all whole-line commands from script.sh, but leave a copy of the original in script.sh.bak.


Trick #4: The .. operator

Perl’s .. operator is a stateful operator — it remembers state between evaluations. As long as its left operand is false, it returns false; Once the left hand returns true, it starts evaluating the right-hand operand until that becomes true, at which point, on the next iteration it resets to false and starts testing the other operand again.


What does that mean in practice? It’s a range operator: It can be easily used to act on a range of lines in a file. For instance, I can extract all GPG public keys from a file using:


     perl -ne 'print if /-----BEGIN PGP PUBLIC KEY BLOCK-----/../-----END PGP PUBLIC KEY BLOCK-----/' FILE<br />

Trick #5: -a

-a turns on autosplit mode – perl will automatically split input lines on whitespace into the @F array. If you ever run into any advice that accidentally escaped from 1980 telling you to use awk because it automatically splits lines into fields, this is how you use perl to do the same thing without learning another, even worse, language.


As an example, you could print a list of files along with their link counts using


ls -l | perl -lane 'print "$F[7] $F[1]"'<br />


Trick #6: -F

-F is used in conjunction with -a, to choose the delimiter on which to split lines. To print every user in /etc/passwd (which is colon-separated with the user in the first column), we could do:
perl -F: -lane 'print $F[0]' /etc/passwd<br />

Trick #7: \K

\K is undoubtedly my favorite little-known-feature of Perl regular expressions. If \K appears in a regex, it causes the regex matcher to drop everything before that point from the internal record of “Which string did this regex match?”. This is most useful in conjunction with s///, where it gives you a simple way to match a long expression, but only replace a suffix of it.

Suppose I want to replace the From: field in an email. We could write something like


perl -lape 's/(^From:).*/$1 Nelson Elhage <nelhage\@ksplice.com>/'<br />


But having to parenthesize the right bit and include the $1 is annoying and error-prone. We can simplify the regex by using \K to tell perl we won’t want to replace the start of the match:


perl -lape 's/^From:\K.*/ Nelson Elhage <nelhage\@ksplice.com>/'<br />

Trick #8: $ENV{}

When you’re writing a one-liner using -e in the shell, you generally want to quote it with ‘, so that dollar signs inside the one-liner aren’t expanded by the shell. But that makes it annoying to use a ‘ inside your one-liner, since you can’t escape a single quote inside of single quotes, in the shell.


Let’s suppose we wanted to print the username of anyone in /etc/passwd whose name included an apostrophe. One option would be to use a standard shell-quoting trick to include the ‘:


perl -F: -lane 'print $F[0] if $F[4] =~ /'"'"'/' /etc/passwd<br />


But counting apostrophes and backslashes gets old fast. A better option, in my opinion, is to use the environment to pass the regex into perl, which lets you dodge a layer of parsing entirely:


env re="'" perl -F: -lane 'print $F[0] if $F[4] =~ /$ENV{re}/' /etc/passwd<br />


We use the env command to place the regex in a variable called re, which we can then refer to from the perl script through the %ENV hash. This way is slightly longer, but I find the savings in counting backslashes or quotes to be worth it, especially if you need to end up embedding strings with more than a single metacharacter.


Trick #9: BEGIN and END

BEGIN { ... } and END { ... } let you put code that gets run entirely before or after the loop over the lines.


For example, I could sum the values in the second column of a CSV file using:


perl -F, -lane '$t += $F[1]; END { print $t }'<br />

Trick #10: -MRegexp::Common

Using -M on the command line tells perl to load the given module before running your code. There are thousands of modules available on CPAN, numerous of them potentially useful in one-liners, but one of my favorite for one-liner use is Regexp::Common, which, as its name suggests, contains regular expressions to match numerous commonly-used pieces of data.


The full set of regexes available in Regexp::Common is available in its documentation, but here’s an example of where I might use it:



Neither the ifconfig nor the ip tool that is supposed to replace it provide, as far as I know, an easy way of extracting information for use by scripts. The ifdata program provides such an interface, but isn’t installed everywhere. Using perl and Regexp::Common, however, we can do a pretty decent job of extracing an IP from ip’s output:


ip address list eth0 | \<br />  perl -MRegexp::Common -lne 'print $1 if /($RE{net}{IPv4})/'<br />





So, those are my favorite tricks, but I always love learning more. What tricks have you found or invented for messing with perl on the command-line? What’s the most egregious perl “one-liner” you’ve wielded, continuing to tack on statements well after the point where you should have dropped your code into a real script?





perl -lne s/rebooting//i


Tired of babysitting your systems while you reboot to install updates? Eliminate reboots with Ksplice Uptrack, and spend that time honing your perl scripts instead!



REFERENCES

http://blog.ksplice.com/2010/05/top-10-perl-one-liner-tricks/


Tuesday, May 18, 2010

Unix find and replace text within all files within a directory

— SkyHi @ Tuesday, May 18, 2010

To replace all instances of a string in a directory (subdirectories included) do:


Code:


perl -e "s/FIND/REPLACE/g;" -pi.save $(find path/to/DIRECTORY -type f)






The above will make a backup temp file of your original

If you do not want a temp file with the .save extension then do:




Code:


perl -e "s/FIND/REPLACE/g;" -pi $(find path/to/DIRECTORY -type f)






--------------------

Example:

You want to replace all instances of the word "design" with "dezine" in the directory /public_html/company/info



you can execute the command from document root as


Code:


perl -e "s/design/dezine/g;" -pi.save $(find public_html/company/info -type f)






or you can execute the command from public_html/company/ (a directory above) as:


Code:


perl -e "s/design/dezine/g;" -pi.save $(find info -type f)






------------------------------



The above commands will search all files (.gif, .jpg, .htm, .html, .txt) so you might see some error messages "Can't open *.gif", etc)



Simplified



To search just files of type, .htm without a backup file in the current directory only (no subdirectories) you could use:




Code:


perl -pi -e 's/design/dezine/g' *.htm







# *****************************************************************************************
# find_and_replace_in_files.sh
# This script does a recursive, case sensitive directory search and replace of files
# To make a case insensitive search replace, use the -i switch in the grep call
# uses a startdirectory parameter so that you can run it outside of specified directory - else this script will modify itself!
# *****************************************************************************************

!/bin/bash
# **************** Change Variables Here ************
startdirectory="/home/gare/tmp/tmp2"
searchterm="search"
replaceterm="replaceTerm"
# **********************************************************

echo "******************************************"
echo "* Search and Replace in Files Version .1 *"
echo "******************************************"

for file in $(grep -l -R $searchterm $startdirectory)
do
sed -e "s/$searchterm/$replaceterm/ig" $file > /tmp/tempfile.tmp
mv /tmp/tempfile.tmp $file
echo "Modified: " $file
done


echo " *** Yay! All Done! *** "








REFERENCES
http://forums.devshed.com/unix-help-35/unix-find-and-replace-text-within-all-files-within-a-146179.html

Perl one-liner Add first line to all perl file

— SkyHi @ Tuesday, May 18, 2010

Example perl one liners for command line use, a summary of important perl command line arguments, and how to convert between 1-liners and full Perl scripts. This page assumes the reader has a reasonable amount of Perl experience. Consult sites like learn.perl.org and Perl Monks to learn more about Perl, or visit the #perl channel on the Freenode IRC network. Also consider the book Minimal Perl by Tim Maher, which covers one liner style Perl in great detail.

The following examples require a Unix shell, such as zsh. Windows systems will need double quotes in place of single quotes.

perl one liners favor quick command line searching and editing. I recommend the practices outlined in Perl Best Practices when developing scripts or applications with Perl. See also Famous Perl One-Liners Explained for additional discussion of Perl one liners.

Learned something? Blog about it!

Perl Argument Overview

Arguments to perl can alter how Perl processes input. For a complete list of these invocation options, see perlrun.

  • -e specifies Perl expressions. More than one can be used, if needed. Other options should not follow this option.
  • $ perl -e 'print "Hello";' -e 'print " World\n"'
    Hello World

    Under Perl 5.10 and higher, the -E option enables various features:

    % perl -E 'say "Hello World"'
    Hello World

  • -p loops over and prints input.
  • -n loops over and does not print input.
  • -l strips newlines on input, and adds them on output. Use this option by default, unless the newlines need special handling, or for efficiency reasons.
  • Use the -ple or -nle option clusters, depending on whether input data should be printed by default or not. The expression 42 does nothing; these examples show the default behavior, and how to enable printing with a -nle.

    $ echo test | perl -ple 42
    test
    $ echo test | perl -nle 42
    $ echo test | perl -nle 'print'
    test

  • -i causes perl to operate on files in-place, and optionally also backs up the files via -i.bak or whatever. I strongly recommend previewing without the -i option before making permanent changes!
  • Never use the -ie '…' invocation, as the -i option reads the e as the backup filename suffix, not the -e as intended. Construct command lines with -e as the last argument before the expression to avoid these sorts of errors:

    # DOS to Unix text convert (example only, dos2unix much faster)
    $ perl -i -pe 's/\r//g' file

    # Legacy MacOS to Unix text convert
    $ perl -i -pe 's/\r/\n/g' file

    # Unix to DOS text convert (unix2dos much faster)
    $ perl -i -pe 's/\n/\r\n/' file

    I shun the backup filename extension to -i, such as -i.bak. Instead, I store data under version control, and thus can revert changes should a sandbox edit go awry. Version control also offers diff support to sanity check the changes made, and commits to log reasons with changes.

  • -a enables auto-split of input into the @F array.
  • Use perl -lane … when processing input into columns: easy to remember (data split into multiple lanes), and handles line breaks via the -l option. Arrays in Perl start at 0, not 1. Also note .. only handles positive ranges (1..2 not 2..1). Use reverse 1..2 to produce a negative trending series.

    $ echo a b c | perl -lane 'print $F[1]'
    b
    $ echo a b c | perl -lane 'print "@F[0..1]"'
    a b
    $ echo a b c | perl -lane 'print "@F[-2,-1]"'
    b c

    Consult perlvar to learn about @F and other special variables.

    Alternatives such as cut or awk may be more efficient for parsing delimited data. Perl functions like getpwent may be better suited to parsing /etc/passwd data.

  • -F specifies the characters to split on with the -a option. Like -i it takes an argument, so should be used apart from other option sets:
  • $ perl -F: -lane 'print $F[0] if !/^#/' /etc/passwd

  • -0 specifies the input record separator. More on this option later.
  • -M lets you load nifty modules such as File::Slurp or IO::All.
  • Life with CPAN covers methods to install perl modules.

  • -d enables debugging mode. For interactive debugging, run something like perl -d -e42, then enter exit when done. I prefer one liners or scripts to any interactive mode.
  • $ perl -d -e42

    Loading DB routines from perl5db.pl version 1.28
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(-e:1): 42
    DB<1> print "Hello World"
    Hello World
    DB<2> exit
    Debugged program terminated. Use q to quit or R to restart,
    use O inhibit_exit to avoid stopping after program termination,
    h q, h R or h O to get additional info.
    DB<3> q

Example One Liners

Experiment with these to practice the expressions; otherwise, make backups in the event an expression runs amok. The examples assume a Unix Bourne compatible shell (such as zsh); other command lines may require altering the quotes around the Perl code (double quotes for Windows), or changes to support C-like shells (csh, tcsh). For more information on shell commands, see my shell tips page.

Current Filename

The special $ARGV variable holds the current filename, or - when data arrives via the standard input filehandle. See perlvar for more information on special variables like $ARGV. As -nle or -ple run code for each line of input, a special block (such as BEGIN or END) or lookup hash must be used if the filename must only be printed once.

$ wc -l /etc/passwd
36 /etc/passwd
$ perl -nle 'END { print $ARGV }' /etc/passwd
/etc/passwd

$ echo test | perl -nle 'print $ARGV'
-
$ (echo test; echo test2) | perl -nle 'print $ARGV'
-
-

$ perl -nle 'print $ARGV if !$seen{$ARGV}++' /etc/passwd /etc/shells
/etc/passwd
/etc/shells

The filename can be used when sending output to a new command that needs the original filename.

  • Include filename in output
  • If looking for data in multiple files, prefix the output with the filename, so the matches can be linked back to the source file. This example searches for unquoted Perl heredoc expressions (<<EOF instead of a more readable <<"END_USAGE"):

    $ perl -nle 'print "$ARGV:$_" if m/<<\s*[A-Z]/' `find . -type f`

    To then edit the matching files with vi, use:

    $ vi `perl -nle 'print $ARGV if m/<<\s*[A-Z]/' `find . -type f``

  • Sendmail Logs
  • The following example matches Sendmail queue strings followed by from=<>, and prints out the filename and queue identifier. The subsequent shell while loop searches for the queue strings in the original file with grep.

    $ perl -nle 'print "$ARGV $1" if /: (\w{14}): from=<>/' /var/log/maillog* \
    | while read filename queueid; do grep $queueid $filename; done

Strip out lines

Use perl -nle 'print if ! …' to say “print, except for the following cases.” Practical uses include omitting lines matching a regular expression, or removing the first line from a file. For more information on regular expressions in Perl, see perlretut and perlreref. Lookup $. in perlvar. Operator precedence may require the use of unless instead of if ! or parenthesized expressions. See perlop for details.

$ (echo a; echo b) | perl -nle 'print if !/b/'
a
$ (echo a; echo b) | perl -nle 'print unless $. == 1'
b

A warning about the special line number variable $. and multiple files: the eof function must be used to reset $. for each new file, as otherwise the line count increases across the files. The following examples demonstrate this behavior by looping over the input file twice; note the use of close ARGV if eof in the second case.

$ cat input
foo
bar
zot
$ perl -nle 'print $.' input input
1
2
3
4
5
6
$ perl -nle 'print $.; close ARGV if eof' input input
1
2
3
1
2
3

Add a line to a file

Appending data to existing files is easy. So is inserting data into arbitrary locations in a file, such as prepending a new first line to a set of files. In the following case, #!/usr/bin/perl will be added as the first line of all *.pl files in the current directory.

$ perl -i -ple 'print q{#!/usr/bin/perl} if $. == 1; close ARGV if eof' *.pl

mod:

$ perl -i -ple "print q{This's rocks!} if $. == 1; close ARGV if eof" *.pl

If a recursive replace is needed, either investigate the use of the modules File::Find or IO::All, or list all the files via a Unix shell command. If filenames contain spaces, use find -print0 and xargs -0 to avoid filenames being misinterpreted by the shell.

$ perl -i -ple 'print q{#!/usr/bin/perl} if $. == 1; close ARGV if eof' \
`find . -type f -name "*.pl"`


$ find . -type f -name "*.pl" -print0 | \
xargs -0 perl -i -ple 'print q{#!/usr/bin/perl} if $. == 1; close ARGV if eof'

The following trick shows how to replace the second line of a file with some text, but only if that line is blank.

$ perl -ple '$_ = "some text" if $. == 2 and m/^$/; close ARGV if eof'

To pipe null delimited data to perl without using xargs -0, supply no argument to the -0 option to perl:

$ find . -type f -print0 | perl -0 -ne 'print "$_\n"'
…

To alter the last line of a file with an in-place edit, use the eof function as a test:

$ (echo one; echo two) > test
$ perl -i -ple 'tr/a-z/A-Z/ if eof' test
$ cat test
one
TWO

Home on the range

To match or skip blocks of text, use the .. operator. perlop details this operater. This example prints lines, unless blank:

$ cat input
foo



bar
$ perl -ne 'print unless /^$/../^$/' input
foo
bar

The unless statement is equivalent to if not, but is different from if ! due to the associativity and precedence rules covered in perlop. A benefit of this behavior allows the reduction of runs of blank lines to a single blank line.

$ perl -ne 'print if ! /^$/../^$/' input
foo

bar

Line numbers can also be used with the range operator, for instance to remove the first four lines of a file.

$ perl -nle 'print unless 1 .. 4' input
bar

To match a single line with the range operator, use 5..5.

Altering record parsing

Perl uses the -0 option to allow changing the input record separator. Use -00 to operate in paragraph mode, and -0777 to treat the file as a single line. The paragraphs file contains the -0 documentation from perlrun, used in the following example:

$ perl -00 -ne 'print if /special/' paragraphs
The special value 00 will cause Perl to slurp files in paragraph
mode. The value 0777 will cause Perl to slurp files whole because
there is no legal byte with that value.

Parsing the entire input file as a single line can be used to alter the newlines that otherwise require a range operator to deal with, as shown above. By treating an entire file as a single line, a s///g expression can eliminate runs of blank lines:

$ cat input
foo



bar
$ perl -0777 -pe 's/\n+/\n/g' input
foo
bar

Match some data with Backreferences

Use backreferences to extract matching data. If matching a single expression, such as words from the paragraphs file, use a for loop to print them all:

$ perl -nle 'print for m/\b(\S+)\b/g' paragraphs
…

A while loop must be used when making multiple backreferences: find the matches, then use the $1 and $2 variables to print the results. Another contrived example: find the words on either side of all the the in a file.

$ perl -nle 'print for m/(\S+)\s+the\s+(\S+)/g' paragraphs
specifies
input
digits,
null
follow
digits.
by
null
use
hexadecimal
where
"H"
use
"-x"
$ perl -nle 'while(m/(\S+)\s+the\s+(\S+)/g){print "$1 $2"}' paragraphs
specifies input
digits, null
follow digits.
by null
use hexadecimal
where "H"
use "-x"

Custom Quoting

Shell quoting may cause problems when writing expressions on the command line. On Unix, wrap Perl expressions in single quotes to prevent unwanted shell interpolation. To use a literal single quote inside a single quoted string, the awkward '\'' syntax ends the single quoted string, include a literal quote, then restart the quoted string:

$ perl -le 'print "'\'' is a single quote"'
' is a single quote

Alternative: use an octal code instead; see ascii(1) for a dictionary of ASCII to octal values.

$ perl -le 'print "\047 is a single quote"'
' is a single quote

The od -bc command will display the octal codes for any data passed to it:

$ perl -le 'print "\047"' | od -bc
0000000 047 012
' \n
0000002
$ perl -le 'print chr for 1..250' | od -bc
…

Perl also allows different quoting operators, see the “Quote and Quote-like Operators” section under perlop for more information on these.

$ perl -le 'print q{single quoted: $$} . qq{ interpolated: $$}'
single quoted: $$ interpolated: 11506

Output to Multiple Files

To split output among multiple files, change where standard output points at based on some test. For example, the following will split a Unix mail file inbox (in mbox format) into multiple files named filename.*, incrementing a number for each message in the mailbox.

$ perl -pe 'BEGIN { $n=1 } open STDOUT, ">$ARGV.$n" and $n++ if /^From /' inbox

Recursive File Mangling

Either the shell or Perl modules can be used to alter files in subdirectories. Perl modules to use include File::Find or File::Find::Rule, among others. Relevant shell commands on Unix include find(1) and xargs(1). Replace the echo in the examples below with the perl command to run on the files. The -print0 argument to find and xargs -0 will work even if files have spaces in their name, unlike the first case.

$ echo `find . -type f`
$ find . -type f -print0 | xargs -0 echo

Fun with @INC

Search under @INC (see perlvar for more information on this array) to find installed Perl modules. This example will search most of @INC for any module names beginning with Config. The shell backticks collapse the directory list into proper arguments for find(1), and the Perl grep excludes non-existent directories and the current directory from the search.

$ find `perl -le 'print for grep {$_ ne q{.}and -d} @INC'` -name "Config*"

Make use of the related %INC hash to find the location of loaded modules on the underlying filesystem:

$ perl -MCPAN -le 'print $INC{"CPAN.pm"}'
/System/Library/Perl/5.8.6/CPAN.pm

Downloading YouTube Videos

Peteris Krumins posted an excellent discussion on downloading YouTube videos with a Perl one-liner.

Converting One Liners

One liners may be used as quick example code, or could be found in someone’s shell history. This may not be the ideal form for commonly used commands. The following section demonstrates how to convert one liners into Perl scripts.

  • Newline handling
  • The -l command line option can easily be ported, simply list it on the shebang line.

    #!/usr/bin/perl -w -l
    use strict;

  • Loop over input (-pe or -ne)
  • Printing loops can be replaced with a while block that prints by default. For a non-printing loop, remove the print statement.

    #!/usr/bin/perl -w -l
    use strict;

    while (<>) {
    # code from -e expressions here

    print;
    } continue {
    close ARGV if eof;
    }

    Special BEGIN or END blocks can be copied in directly, or placed before and after the while loop in the main namespace.

  • In Place Editing
  • To convert the -i in-place option, use the $^I variable (perldoc perlvar), and ensure the files to be processed are in @ARGV before looping over <>.

    # trick to expand globs in input for systems with poor shells (Windows)
    local @ARGV = map glob, @ARGV;

    local $^I = '.orig';

    while (<>) {
    # code here

    print;
    } continue { close ARGV if eof }

    Consider also the File::AtomicWrite module to help with atomic file writes.

END without END

-ple '$c++; END { print $c }' can also be written as -ple '$c++ }{ print $c'.


REFERENCES

http://sial.org/howto/perl/one-liner/

Linux: How do I mass find and replace text in files under linux using perl?

— SkyHi @ Tuesday, May 18, 2010

Few friends have asked me how to do mass find and replace text in files under linux. There are quite a bit of options in linux to achieve mass replacing of text in files. If you are doing it file by file, you can achieve that in vi by opening, running replace and closing and going to next file. But sometimes that can be very tedious and you would rather do mass replacement on all files containing certain extension. We can do this by using sed or perl. Since most people are familiar with perl (at least most system admins and programmers), I will show you a perl way of doing it which you can use with sed as well if you wish. First step is to get perl to do what we want on one file


perl -w -i -p -e "s/search_text/replace_text/g" filename


-w turns warnings on

-i makes Perl operate on files in-place (if you would like to make backups, use -i.bak, this will save filename.bak files)

-p loops over the whole input

-e specifies Perl expression

filename works on one file at a time


Once we get the results we want, we can now pass it multiple files by doing something like:


perl -w -i -p -e "s/search_text/replace_text/g" *.php


This will search and replace within all php files in the directory you are in.


Now, let us say you want to go through your whole web directory and replace every place where you have “Perl is good” to “Perl is great”, you would use following command:


find /www_root -name "*.php"|xargs perl -w -i -p -e "s/Perl is good/perl is great/g"


find will start at /www_root, look for filenames which have .php extension, xargs takes that filename and passes it to perl as an arguement.


REFERENCES
http://crazytoon.com/2007/10/29/linux-how-do-i-mass-find-and-replace-text-in-files-under-linux-using-perl/

Perl find and replace

— SkyHi @ Tuesday, May 18, 2010

1. The good - The simple case

Sometimes you want to change the same pattern in a lot of files. How can you do that?

Now, vi and emacs can both open a lot of files, eg: vi *.html. And you can then do a search and replace on the same pattern. But here's a neat perl trick that sometimes comes in useful:

Suppose you have a bunch of files (file1, file2, file3 etc) which have the same chunk of text in them. Eg, the text:

Newspapers are about news.

In a fit of disgust at the tripe that is printed in the Sunday Spurt, you decide to change the statement to

Newspapers are about selling advertising space.

Then this perl in-place edit one-liner comes in handy here:

$ perl -pi -e 's/about news\.$/about selling advertising space\./' file*

Tada! You're done.

The flags (perldoc perlrun) work like this:

-p              loop and swallow the files, and print default.

-i edit the files in-place

-e do the command

REFERENCES
http://www.debian-administration.org/articles/298





=================================================================

How to do a search and replace over multiple files

You could also use find and sed, but I find that this little line of perl works nicely.

perl -pi -w -e 's/search/replace/g;' *.php
-e means execute the following line of code.
-i means edit in-place
-w write warnings
-p loop

Example I had the following style sheet in a section:

<link rel="stylesheet" type="text/css" href="../includes/style.css">

and I wanted the following instead:

<link rel="stylesheet" type="text/css" href="admin.css">

As each expression is a regular expression you've got to escape the special characters such as forward slash and .

\.\.\/includes\/style\.css

So the final line of code ends up as

perl -pi -w -e 's/\.\.\/includes\/style\.css/admin\.css/g;' *.php

REFERENCES
http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php


==============================================================================

Perl Oneliner: Recursive Search and Replace

If you’ve used Perl at all you are probably familiar with the simple oneliner to do a search and replace on a given string:

perl -p -i -e 's/oldstring/newstring/g' *

This will replace all occurrences of oldstring with newstring in all of the files in your current directory. Being able to do this quickly and easily is absolutely awesome, but what if you want to do this recursively across the current directory and all directories below that? I’m sure that there are plenty of ways to do this, the one below is the method that seems the easiest:

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name *.html`

If you wanted to be more precise you could replace find with grep and only perform the search and replace on files that you know already contain oldstring, like this:

perl -p -i -e 's/oldstring/newstring/g' `grep -ril oldstring *`

This is one of those things that I don’t have to do very often, but when I do, this Perl oneliner is a real life saver.


REFERENCES
http://joseph.randomnetworks.com/archives/2005/08/18/perl-oneliner-recursive-search-and-replace/




=============================================================
$ perl -pi.bak -e 's/host\-ip 5\\\.3\\\.220\\\.101/host\-ip 5\.3\.220\.102;' c:\ips-test\*.txt
===================================================================================






Thursday, February 25, 2010

Ping Monitoring Over a WAN - Adding Perl Mods

— SkyHi @ Thursday, February 25, 2010
A couple of modules that we use in our ping monitoring script are Mail::Sendmail and Net::Ping::External. To install these, use the CPAN shell to search for the available Sendmail mods:

root@srv-1 root # <b>perl -MCPAN -e shell</b>
Warning [/etc/inputrc line 28]: Re-binding char #27 from [F_ViEndInsert]
to meta for [91 49 126] => BeginningOfLine.
cpan shell -- CPAN exploration and modules installation (v1.70)
ReadLine support enabled
cpan>
cpan> <b>i /Sendmail/</b>
CPAN: Storable loaded ok
Going to read /root/.cpan/Metadata
Database was generated on Sun, 08 Jun 2003 09:14:27 GMT
Distribution C/CY/CYING/Sendmail-Milter-0.18.tar.gz
Distribution D/DR/DREDD/Sendmail-AccessDB-0.07.tar.gz
Distribution M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz
Distribution M/MS/MSERGEANT/AxKit-XSP-Sendmail-1.4.tar.gz
Module AxKit::XSP::Sendmail (M/MS/MSERGEANT/AxKit-XSP-Sendmail-1.4.tar.gz)
Module Config::Manager::SendMail (S/ST/STBEY/Config-Manager-1.4.tar.gz)
Module Fatal::Sendmail (A/AS/ASKSH/glist-0.9.17a10.tar.gz)
Module Log::Dispatch::Email::MailSendmail (D/DR/DROLSKY/Log-Dispatch-2.06.tar.gz)
Module Mail::Mailer::sendmail (G/GB/GBARR/MailTools-1.15.tar.gz)
Module Mail::Sendmail (M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz)
Module Mail::Transport::Sendmail (M/MA/MARKOV/Mail-Box-2.042.tar.gz)
Module Sendmail::AccessDB (D/DR/DREDD/Sendmail-AccessDB-0.07.tar.gz)
Module Sendmail::Milter (C/CY/CYING/Sendmail-Milter-0.18.tar.gz)
Module SyslogScan::SendmailLine (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module SyslogScan::SendmailLineClone (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module SyslogScan::SendmailLineFrom (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module SyslogScan::SendmailLineTo (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module SyslogScan::SendmailLineTrans (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module SyslogScan::SendmailUtil (R/RH/RHNELSON/SyslogScan-0.32.tar.gz)
Module Tindermail::Sendmail (Z/ZL/ZLIPTON/Devel-Tinderclient-1.2.zip)
20 items found
cpan>

Let's install the correct module:

<b>install Mail::Sendmail</b><br />Running install for module Mail::Sendmail<br />Running make for M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz<br />LWP not available<br />CPAN: Net::FTP loaded ok<br />Fetching with Net::FTP:<br />ftp://archive.progeny.com/CPAN/authors/id/M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz<br />CPAN: Digest::MD5 loaded ok<br />LWP not available<br />Fetching with Net::FTP:<br />ftp://archive.progeny.com/CPAN/authors/id/M/MI/MIVKOVIC/CHECKSUMS<br />CPAN: Compress::Zlib loaded ok<br />Checksum for /root/.cpan/sources/authors/id/M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz ok<br />Scanning cache /root/.cpan/build for sizes<br />Mail-Sendmail-0.79/<br />Mail-Sendmail-0.79/Todo<br />Mail-Sendmail-0.79/README<br />Mail-Sendmail-0.79/MANIFEST<br />Mail-Sendmail-0.79/test.pl<br />Mail-Sendmail-0.79/Sendmail.pm<br />Mail-Sendmail-0.79/Changes<br />Mail-Sendmail-0.79/Makefile.PL<br />Mail-Sendmail-0.79/Sendmail.html<br />CPAN.pm: Going to build M/MI/MIVKOVIC/Mail-Sendmail-0.79.tar.gz<br />Checking if your kit is complete...<br />Looks good<br />Writing Makefile for Mail::Sendmail<br />**********************************************************************<br />NOTE<br />----<br />The test (test.pl) is a real test for this module: it sends an e-mail.<br />You may want to edit test.pl before running it (directly or through<br />make test), so the mail is sent to you. If you also leave my address,<br />the mail goes into a database from which I can get statistics.<br />Read the docs, and have fun...<br />**********************************************************************<br />cp Sendmail.pm blib/lib/Mail/Sendmail.pm<br />Manifying blib/man3/Mail::Sendmail.3pm<br />/usr/bin/make  -- OK<br />Running make test<br />PERL_DL_NONLAZY=1 /usr/bin/perl "-Iblib/lib" "-Iblib/arch" test.pl<br />1..2<br />Test Mail::Sendmail 0.79<br />Trying to send a message to the author (and/or whoever if you edited test.pl)<br />(The test is designed so it can be run by Test::Harness from CPAN.pm.<br />Edit it to send the mail to yourself for more concrete feedback. If you<br />do this, you also need to specify a different mail server, and possibly<br />a different From: address.)<br />Current recipient(s): 'Sendmail Test <sendmail@alma.ch>'<br />ok 1<br />Server set to: mail.alma.ch<br />Sending...<br />content of $Mail::Sendmail::log:<br />Mail::Sendmail v. 0.79 - Sun Jun  8 14:02:50 2003<br />Date: Sun, 8 Jun 2003 14:02:50 -0700<br />Server: mail.alma.ch Port: 25<br />From: sendmail@alma.ch<br />Subject: Mail::Sendmail version 0.79 test<br />To: sendmail@alma.ch<br />Result: 250 Ok: queued as 5F1627FCC<br />ok 2<br />/usr/bin/make test -- OK<br />Running make install<br />Installing /usr/lib/perl5/site_perl/5.8.0/Mail/Sendmail.pm<br />Installing /usr/man/man3pm/Mail::Sendmail.3pm<br />Writing /usr/lib/perl5/site_perl/5.8.0/i686-linux/auto/Mail/Sendmail/.packlist<br />Appending installation info to /usr/lib/perl5/5.8.0/i686-linux/perllocal.pod<br />/usr/bin/make install  -- OK<br />cpan> <br /></sendmail@alma.ch>

The Sendmail module is all happy. Let's grab the Ping test module:

cpan> <b>i /Ping/</b><br />Author          PING ("Ping Liang" <ping07642@netscape.net>)<br />Distribution    B/BB/BBB/Net-Ping-2.30.tar.gz<br />Distribution    C/CO/COLINM/Net-Ping-External-0.11.tar.gz<br />Distribution    P/PI/PING/PBJ-JNI-0.1.tar.gz<br />Distribution    R/RC/RCAPUTO/POE-Component-Client-Ping-0.98.tar.gz<br />Distribution    R/RI/RIIKI/Net-Arping-0.02.tar.gz<br />Distribution    T/TE/TEVERETT/Win32-PingICMP-0.02.tar.gz<br />Module          Fwctl::Services::ping (F/FR/FRAJULAC/Fwctl-0.28.tar.gz)<br />Module          HTML::Bricks::Mappings (P/PE/PETERMCD/HTML-Bricks-0.03.tar.gz)<br />Module          Log::Agent::Stamping (M/MR/MROGASKI/Log-Agent-0.304.tar.gz)<br />Module          Net::Arping     (R/RI/RIIKI/Net-Arping-0.02.tar.gz)<br />Module          Net::Gnutella::Packet::Ping (I/IW/IWADE/Net-Gnutella-0.1.tar.gz)<br />Module          Net::IDN::Nameprep::Mapping (M/MI/MIYAGAWA/Net-IDN-Nameprep-0.02.tar.gz)<br />Module          Net::Lyskom::TextMapping (C/CD/CDYBED/Net-Lyskom-1.0.tar.gz)<br />Module          Net::Peep::Client::Pinger (S/ST/STARKY/Net-Peep-0.4.5.1.tar.gz)<br />Module          Net::Peep::Client::Pinger::Host (S/ST/STARKY/Net-Peep-0.4.5.1.tar.gz)<br />Module          Net::Ping       (B/BB/BBB/Net-Ping-2.30.tar.gz)<br />Module          Net::Ping::External (C/CO/COLINM/Net-Ping-External-0.11.tar.gz)<br />Module          Nmap::Scanner::Util::PingScanner (M/MA/MAXSCHUBE/Nmap-Scanner-0.01.tar.gz)<br />Module          POE::Component::Client::Ping (R/RC/RCAPUTO/POE-Component-Client<br />-Ping-0.98.tar.gz)<br />Module          VBTK::Wrapper::Ping (B/BS/BSHENRY/VBTK-0.14.tar.gz)<br />Module          Win32::PingICMP (T/TE/TEVERETT/Win32-PingICMP-0.02.tar.gz)<br />22 items found<br />cpan> <br />cpan> <b>install Net::Ping::External</b><br />Running install for module Net::Ping::External<br />Running make for C/CO/COLINM/Net-Ping-External-0.11.tar.gz<br />LWP not available<br />Fetching with Net::FTP:<br />ftp://archive.progeny.com/CPAN/authors/id/C/CO/COLINM/Net-Ping-External-0.11.tar.gz<br />LWP not available<br />Fetching with Net::FTP:<br />ftp://archive.progeny.com/CPAN/authors/id/C/CO/COLINM/CHECKSUMS<br />Checksum for /root/.cpan/sources/authors/id/C/CO/COLINM/Net-Ping-External-0.11.tar.gz ok<br />Net-Ping-External-0.11/<br />Net-Ping-External-0.11/Changes<br />Net-Ping-External-0.11/External.pm<br />Net-Ping-External-0.11/MANIFEST<br />Net-Ping-External-0.11/Makefile.PL<br />Net-Ping-External-0.11/test.pl<br />Net-Ping-External-0.11/README<br />CPAN.pm: Going to build C/CO/COLINM/Net-Ping-External-0.11.tar.gz<br />Checking if your kit is complete...<br />Looks good<br />Writing Makefile for Net::Ping::External<br />cp External.pm blib/lib/Net/Ping/External.pm<br />Manifying blib/man3/Net::Ping::External.3pm<br />/usr/bin/make  -- OK<br />Running make test<br />PERL_DL_NONLAZY=1 /usr/bin/perl "-Iblib/lib" "-Iblib/arch" test.pl<br />1..6<br />ok 1<br />ok 2<br />ok 3<br />ok 4<br />ok 5<br />ok 6<br />Running a more verbose test suite.<br />-------------------------------------------------<br />Net::Ping::External version: 0.11<br />6/6 tests passed.<br />Successful tests:<br />use Net::Ping::External qw(ping)<br />ping(host => '127.0.0.1')<br />ping(host => '127.0.0.1', timeout => 5)<br />ping(host => 'some.non.existent.host')<br />ping(host => '127.0.0.1', count => 10)<br />ping(host => '127.0.0.1', size => 32)<br />Operating system according to perl: linux<br />Operating system according to `uname -a` (if available):<br />Linux srv-1.signalq.com 2.4.20-gentoo-r5 #1 Thu May 22 05:34:28 PDT 2003 i686 <br />Intel(R) Pentium(R) 4 CPU 1.70GHz GenuineIntel GNU/Linux<br />Perl version: This is perl, v5.8.0 built for i686-linux<br />-------------------------------------------------<br />If any of the above tests failed, please e-mail the bits between the dashed<br />lines to colinm@cpan.org. This will help me in fixing this code for maximum<br />portability to your platform. Thanks!<br />/usr/bin/make test -- OK<br />Running make install<br />Installing /usr/lib/perl5/site_perl/5.8.0/Net/Ping/External.pm<br />Installing /usr/man/man3pm/Net::Ping::External.3pm<br />Writing /usr/lib/perl5/site_perl/5.8.0/i686-linux/auto/Net/Ping/External/.packlist<br />Appending installation info to /usr/lib/perl5/5.8.0/i686-linux/perllocal.pod<br />/usr/bin/make install  -- OK<br />cpan> <br /></ping07642@netscape.net>

We heart the CPAN modules system.

Don't rely on this script for production servers unless you know exactly what you are doing, and are sure that this script fits your needs. Do feel free to encorporate bits of the script as you need, or the whole script if you desire. Credit NetAdminToools, though, if you feel like it. :) Please read our terms of use.

There are five parts to this article:
Introduction
Main Routine
Check/Log Routines
Adding Perl Mods
pf and rf routines

REFERENCE
http://www.netadmintools.com/art274.html