Perl basics: a quick introduction for Unix users
Perl was built for Unix text processing and system administration, and it is still installed on nearly every Unix and Linux system. Even if you write new programs in another language, a little Perl lets you read old scripts and write one-liners that do what sed and awk cannot.
Running Perl
perl -v # version (5.32 to 5.42 on current distributions)
perl -e 'print "Hello\n"' # run code from the command line
perl script.pl # run a script
A script starts like this. The two use lines catch most mistakes, so always include them:
#!/usr/bin/perl
use strict;
use warnings;
print "Hello, world\n";
Variables
Perl marks the type of a variable with its first character:
my $name = "Ann"; # scalar: one value (string or number)
my @users = ("ann", "bob", "eve"); # array: an ordered list
my %uid = (ann => 1001, bob => 1002); # hash: key/value pairs
print "First user: $users[0]\n";
print "Number of users: ", scalar(@users), "\n";
print "Bob's UID: $uid{bob}\n";
for my $u (@users) {
print "user $u\n";
}
for my $k (sort keys %uid) {
print "$k => $uid{$k}\n";
}
my declares a variable; use strict makes it compulsory, which catches spelling mistakes.
Conditions and loops
if ($count > 10) {
print "many\n";
} elsif ($count == 0) {
print "none\n";
} else {
print "a few\n";
}
print "admin\n" if $user eq "root"; # statement modifier
die "no file given\n" unless @ARGV; # @ARGV holds the arguments
Compare numbers with ==, <, > and strings with eq, ne, lt, gt. Mixing them up is the most common beginner bug.
Reading files
open(my $fh, '<', '/etc/passwd') or die "cannot open: $!\n";
while (my $line = <$fh>) {
chomp $line; # remove the newline
my ($user, undef, $uid, $gid, undef, $home, $shell) = split /:/, $line;
print "$user uses $shell\n" if $uid >= 1000;
}
close $fh;
Use '>' to write a file and '>>' to append. $! holds the system error message.
Regular expressions
Regular expressions are built into the language, which is why Perl is so good at text. Perl's syntax became the model for regexes in Python, PHP, JavaScript and grep -P.
if ($line =~ /error/i) { print "found\n" } # match, ignore case
if ($date =~ /^(\d{4})-(\d\d)-(\d\d)$/) { print "year $1\n" } # capture groups
(my $clean = $text) =~ s/\s+/ /g; # replace runs of whitespace with one space
my @words = split /\s+/, $text;
my $n = () = $text =~ /\bthe\b/g; # count matches
One-liners
Perl's command-line switches make it a more powerful sed or awk:
# print lines matching a pattern (like grep -P)
perl -ne 'print if /ERROR \d{3}/' app.log
# edit files in place, keeping a backup (like sed -i)
perl -pi.bak -e 's/old.example.com/new.example.com/g' *.conf
# print the third field of each line (like awk '{print $3}')
perl -lane 'print $F[2]' data.txt
# sum a column
perl -lane '$s += $F[4]; END { print $s }' sizes.txt
# replace across lines: join the lines of each paragraph, keep blank lines between paragraphs
perl -0777 -pe 's/(?<=\S)\n(?=\S)/ /g' notes.txt
| Switch | Meaning |
|---|---|
-e | Run this code |
-n | Loop over input lines, do not print |
-p | Loop over input lines and print each one |
-i | Edit files in place (with an optional backup suffix) |
-l | Remove newlines on input, add them on output |
-a, -F | Split each line into @F (on whitespace, or on the -F pattern) |
-0777 | Read the whole file at once |
Running commands
my @lines = `df -h`; # capture output (avoid with untrusted input)
system('systemctl', 'reload', 'nginx') == 0
or die "reload failed: $?\n"; # list form: no shell involved
Use the list form of system when any argument comes from outside the program, so that no shell interprets it.
Modules and CPAN
CPAN, the Comprehensive Perl Archive Network, holds over 200,000 modules. Install them from your distribution where possible (apt install libjson-perl, dnf install perl-JSON) so they get security updates; otherwise use cpanm.
use JSON::PP; # included with Perl
use File::Find; # walk directory trees
use Getopt::Long; # command-line options
use Time::Piece; # dates
Learn more
- perldoc.perl.org: the official documentation, including perlintro and perlretut (the regex tutorial). Locally:
perldoc perlintro. - learn.perl.org: tutorials and book list.
- Perl Maven tutorial.
- MetaCPAN: search CPAN modules and their documentation.