Perl Oneliners
Perl is a fantastic language that unfortunately has been eclipsed by other more popular languages.
Despite the lack of popularity for application programming Perl is still ubiquitous, you can use it everywhere for small tasks.
Even if you are not planning to use it to develop your next big application and even if you are not going to learn the depth of the language my hope that this book will provide you with useful oneliners that you can use as a helper tool for your daily tasks.
About the author:
Gabor has been programming since 1983 and he has been using Perl since 1994. Give or take a few months. He has been teaching Perl since 2000.
Install Perl
Follow the instructions on the Perl web site.
Linux
Most Linux distributions include perl, but if it is not installed then you can use your regular package-management system to install the perl
or Perl
package.
Debian/Ubuntu/etc.
apt install perl
macOS
Perl should come with the Operating System
Windows
Strawberry Perl is the community packaging of Perl for Windows.
Oneliners
Print the version of Perl
Before we get into the more interesting things, let's make sure that we have perl
installed on the system and we can run it by printing the version number of the installed perl.
Open a terminal or on Windows open a CMD window and type in the following:
perl -v
The response I got on my Ubuntu Plucky Puffin (aka. 2025.04) is the following:
This is perl 5, version 40, subversion 1 (v5.40.1) built for
x86_64-linux-gnu-thread-multi
(with 48 registered patches, see perl -V for more detail)
Copyright 1987-2025, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.
The long flag should give you the same output:
perl --version
Detailed version information
Using capital -V
flag will give you a lot of details about the current version of perl. Most of which is probably not interesting so I won't bore you with explanations now.
However, you are welcome to try in and marvell about the details.
perl -V
Latest Perl?
Perl.org indicates that the latest stable version is 5.42. It is recommended that you use the latest stable version, but for the examples in this book you can probably use much older versions of Perl as well.
Print a number, use Perl as your calculator
You can execute any perl code that you provide on the command line as the value of the -e
or the -E
flag. The difference between the two is that -E
enables all optional features and builtin functions
that were added since version 5.10 came out in, well a very long time ago.
The first such extra that we get using -E
is the say
function.
print
will print the value after itsay
will also print the value after it, but it will also print a newline.\n
at the end.
perl -e "print 42"
perl -E "say 42"
Forgetting the -E
flag
What happens if you try to use the say
function, but mistakenly use the -e
flag? You get an error:
$ perl -e "say 42"
Number found where operator expected (Do you need to predeclare "say"?) at -e line 1, near "say 42"
syntax error at -e line 1, near "say 42"
Execution of -e aborted due to compilation errors.
Calculator
You can use perl on the command line as a calculator:
$ perl -E "say 19 * 23"
437
$ perl -E "say 19 + 23"
42
- -e
- -E
- say
Print a string
perl -E "say q(hello world)"
grep on Windows as well
Lacking grep on Windows, search for all the occurrences of the 'secret' in my xml files.
In a single file:
perl -ne "print if /secret/" main.xml
As Windows does not know how to handle wildcards on the command line,
we cannot supply *.xml
and expect it to handle all the xml files.
We help it with a small BEGIN
block. $ARGV
holds the name of the current file
perl -ne "BEGIN{ @ARGV = glob '*.xml'} print qq{$ARGV:$_} if /secret/"
Rename many files
- Rename every .log file adding an extra extension of .old
perl -e "rename $_, $_ . '.old' for glob '*.log'"
- Rename every .log file replacing .log with a timestamp
perl -e "$t = time; rename $_, substr($_, 0, -3) . $t for glob '*.log'"
- rename
- glob
Replace a string in many files
You have a bunch of text files in your directory mentioning the name:
"Microsoft Word"
You are told to replace that by
"OpenOffice Write"
perl -i -p -e "s/Microsoft Word/OpenOffice Write/g" *.txt
-i = inplace editing
-p = loop over lines and print each line (after processing)
-e = command line script
- -i
- -p
Replace one line with an empty row
perl -i -p -e 's/^date://' *.txt
Change encoding
Convert all the .srt files that are Windows Hebrew encoded to UTF-8 keeping a backup copy of the original file with a .bak extension.
-i - inplace editing
.bak - generate backup with that extension
-M - load module as 'use' would do
-p - go over line by line on the file, put the line in $_, execute the
command on it and then print the result.
In case of inplace editing, save it back to the file.
perl -i.bak -MEncode -p -e "Encode::from_to($_, 'Windows-1255', 'utf-8')" video.srt
use Encode;
foreach $file (@ARGV) {
copy $file, "$file.bak";
}
while (<>) {
Encode::from_to($_, 'Windows-1255', 'utf-8');
print $_;
}
- -i
- -M
- -p
- Encode
print the 3rd field of every line in a CSV file
You have a number of csv files, you want to print the 3rd field of each row of each file.
perl -n -a -F, -e 'print "$F[2]\n"' *.csv
-n = loop over lines but do NOT print them
-a = autosplit by ' '
-F, = replace the split string by ','
You want to make sure all the rows are 4 elements long. Print out file name and line number of all the bad rows.
perl -a -F, -n -e 'print "$ARGV:$.\n" if @F != 4' data.csv
- CSV
- -n
- -a
- -F
Print all usernames from /etc/passwd
perl -n -a -F: -e 'print "$F[0]\n"' /etc/passwd
Remove one line from a file
I had a thousand YAML files that, for historical reasons, had a field called date:
. At one point update the code processing these files and wanted to remove this date
field from all the files.
For example the one that starts with date:
perl -i -n -e 'print $_ if $_ !~ /^date:/' *.yaml
-i
means inplace editing, that is the output replaces the input file-n
means go over the input file(s) line by line.-e
means, here comes the code.
In the code
$_
represents the current line/^date:/
is a regular expression where the two slashes are the delimeters.^
means our regex has to match the beginning og the string.date:
is just the string we match.!~
is the regex not match operator. (=~
is the regex match operator)- So this expression
$_ !~ /^date:/
checks if the current line starts withdate:
. - Just like natural languages, perl also allows reversing the order of a conditional statement. So instead of
if (condition) { do_something }
we can writedo_something if condition
. - We print the current line if id does not start with
date:
.
We can improve our code:
$_
is the default for print
We don't need to explicitelly print the content of $_
if we just write print
without telling perl what to print it will print the content of $_
.
perl -i -n -e 'print if $_ !~ /^date:/' *.yaml
Use boolean not
and the matching operator
Intead of the !~
"not match" operator we could use the match operator =~
and then use a boolean not
:
perl -i -n -e 'print if not $_ =~ /^date:/' *.yaml
This in itself probbaly isn't an improvement, but the matching operator also defaults to work on $_
if no parameter provided.
Actually for this to work we even remove the match operator. If we have a regular expression without a matchin (or not-matching)
operator then it defaults to work on the content of $_
. Neat.
perl -i -n -e 'print if not /^date:/' *.yaml
Use unless
Another potential improvement to our code is using the unless
keyword which is the same as if not
.
perl -i -n -e 'print unless /^date:/' *.yaml