[ Perl tips index ]
[ Subscribe to Perl tips ]
Occasionally we find a task that only ever needs to be done once. Perhaps
we need to change a file so that all strings A002 become B005, or we
want to find out how many times a particular IP address accesses the
web-server today. In these cases, rather than use a throw-away script, we
may be able to write our script directly onto the command line.
Keep in mind as you do this though, that sometimes throw-away scripts turn into programs that become essential to the business. If you think you're ever likely to run this same program again, or if it is non-trivial, write it into a program, comment it, use strict and warnings, as well as the appropriate modules and keep it. You'll be glad you did.
Let's say that you've got a timestamp in seconds from the epoch; the number of seconds since midnight, 1st January, 1970 GMT. This time format is used by a number of applications, and has the advantage of being an absolute measurement of time that is independent of timezone or daylight savings. It's also completely useless to most humans. By default, the squid proxy server records times in seconds from the epoch.
We can use Perl to convert epoch-time to local time very easily,
and we can do so on the command-line using Perl's execute switch,
-e:
perl -e 'print scalar(localtime(1150946643)).qq{\n}';
Under Perl 5.10, we can use the capital -E switch to execute
code, but turning on all the new 5.10 features first:
perl -E 'say scalar localtime(1150946643)'
The qq{\n} represents a newline character, which you may more commonly
see written as "\n". We use scalar to force localtime into a
scalar context. Without this, Perl would instead return us a long list
consisting of the year, month, time, hour, minute, second and so forth.
Not exactly what we're after.
When writing a script on the command line, it's always recommended
that you use q{} for single quotes, and qq{} for double quotes.
This avoids any unwanted interaction with the shell, and can also make
your code visually easier to read.
To perform multiple operations, just use semi-colons between your statements, in the same way that you do in a program:
perl -e 'foreach(<*.txt>) { s/.txt$//; rename(qq{$_.txt},qq{$_-2006.txt}) }'
This moves all files with a .txt extension to instead end with
-2006.txt.
When using the -e and -E switches, you need to be very careful
of interactions with the shell. Most Unix shells pass single-quoted
strings to the application without alteration. DOS and Windows
shells, on the other hand, use double quotes for this purpose:
# Unix, single-quotes
perl -e'print scalar(localtime(1150946643)).qq{\n};'
# Windows, double-quotes
perl -e"print scalar(localtime(1150946643)).qq{\n};"
In these notes we'll be using single-quotes when working on the command-line. If you're working on a Windows system, then you'll need to change these to double-quotes before trying any examples.
You may have a snippet of Perl that you wish to execute, perhaps from an e-mail or web page, but which you don't want to save as a permanent program. In that case you can invoke Perl and give it a script on STDIN:
% perl
foreach(<*.txt>) {
s/.txt$//;
rename("$_.txt","$_-2006.txt");
}
This will tell you of syntax errors immediately, but script execution will
not start until you send Perl an end-of-file character, or more
commonly known as EOF. On Unix systems this is done by hitting
CTRL-D at the start of a line, and under Windows is done by hitting
CTRL-Z at the start of a line.
If your program accepts input from STDIN, you will need to provide its
input after you've sent the EOF character and then send EOF
again. In this case, you're almost certainly better off writing your
code into a file.
Using -p tells Perl to act as a stream editor. It will read
input from STDIN, or from files mentioned on the command line, and
place each line of input into $_. The body of your program is
then executed, and the contents of $_ are printed. It's most
commonly used with Perl's substitution operator s///, which is
covered in the regular expressions chapters of this course.
The following command line snippet can be used to correct a common spelling mistake in one of our documents:
perl -pe 's/freind/friend/g' essay.txt > spellchecked-essay.txt
It's the same as writing:
while(<>) {
s/freind/friend/g;
print;
}
As a more advanced example, the following snippet can be used to convert seconds from the epoch time-stamps into human readable dates for squid logfiles:
perl -pe's/^([\d.]+)/localtime($1)/e' access.log
It works by finding a number at the start of each line (the timestamp),
and replacing it with the result of calling localtime on that
timestamp.
perl -ne 'print if /perltraining\.com\.au/'
Using -n makes Perl act almost the same as -p. However, the print
line is excluded. This allows us to write code like the above which only
prints when we want it to. It is equivalent to:
while(<>) {
print if /perltraining\.com\.au/;
}
Perl has a great number of useful modules, and we may wish to use
these on command-line programs. We can load them quickly and easily
using the -M switch. The following example prints what Perl
can find in our environment using Data::Dumper:
perl -MData::Dumper -e 'print Dumper(\%ENV);'
Multiple modules can be used by including multiple -M flags.
If you need to provide options to the module, you can do so as follows:
perl -MFatal=open,close -e 'open(my $file, q{> /tmp/foo});
print {$file} qq{12345\n};'
The above program will die with an error if the open fails, even though
we are not explicitly catching this error. This is because of our use of
the Fatal module. It is equivalent to:
use Fatal qw(open close);
open(my $file, q{> /tmp/foo});
print {$file} qq{12345\n};
For more information on these switches read perldoc perlrun. Further
switches will be covered in a later tip.
[ Perl tips index ]
[ Subscribe to Perl tips ]
This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.
If you have any questions please don't hesitate to contact us:
| Email: | contact@perltraining.com.au |
| Phone: | 03 9354 6001 (Australia) |
| International: | +61 3 9354 6001 |
Copyright 2001-2012 Perl Training Australia. Contact us at contact@perltraining.com.au