Perl basics: a quick introduction for Unix users

Updated November 2026

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
SwitchMeaning
-eRun this code
-nLoop over input lines, do not print
-pLoop over input lines and print each one
-iEdit files in place (with an optional backup suffix)
-lRemove newlines on input, add them on output
-a, -FSplit each line into @F (on whitespace, or on the -F pattern)
-0777Read 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