Perl Information Center Tutorials - One Liner Basics
These tutorials were written to help you get a quick, but thorough, understanding of Perl -
the scope of the language as well as it's specific capabilities.
| Beginners
| Built-In Functions
| Advanced
| CGI Applications
|
|
|
|
|
|
One Liners
Perl allows a complete, single line script to be run from the command line.
These 'one liners' can be a quick way of making changes, finding information
or presenting file content.
Most Perl programmers don't use one liners and are happy to use more
relaxed, readable code in standard multi-line script files. Other programmers
enjoy the speed and convenience of one liners or simply enjoy the challenge
of cramming as much code/logic into one line as possible.
The following three sections provide information on how to create one liners,
over 75 scripts, and detailed explanation of how the scripts work.
Constructing One Liners
All one liners use Perl at the command line with the -e switch, which tells Perl that
code will be supplied from the command line rather than from a file. Additional (but optional)
switches, input text file names, piping and redirection (which are a function of the operating
system shell) can also be used to make one liners even more versatile.
Here's the basic one liner structure. You'll see that the Hello World example (repeated here)
fits this structure, with the optional file name removed.
perl -e " " filename.txt # code + optional file name
perl -e "print 'Hello World!'" # with Perl code, no file name
Many useful one liner scripts are that simple, while others are somewhat more
complicated. This page walks you through the following topics, providing
information you'll need to know to write a full range of one liners.
One Liner Length
Most one liners are usually no more than a standard 80 character line of text.
Almost all of one liners provided on this page fall into that category.
However, a one liner can actually be fairly long. On Windows XP the maximum length of
the command line is 8191 characters (2047 characters for earlier versions of Windows).
So the term one liner is slightly misleading since a command line can take far more
than the 80 character width of a standard display line of text.
One Liners and Windows
Unfortunately, Perl programs don't always work in Windows exactly as they do
on Unix. Sometimes, a script that works on Unix won't even work on Windows.
I decided to focus this tutorial on running Perl one liners on Windows
and have verified that all of the one liners scripts will run correctly on a PC.
I have not verified that they will work on Unix.
For example, the Windows command line requires double quotes around the code, whereas
Unix supports both single and double single quotes. This and other Windows/Unix issues
are discussed in more detail below.
Using Files
The -e switch tells Perl to expect the script (in quotes), optionally followed by one
or more file names. The content of the file names are fed to the one liner program,
one after the other, via STDIN. A single file name, or multiple file names separated
by a space are supported by Windows. Filename wildcards are supported by Unix, but
not by Windows. Wildcard workarounds for Windows are discussed below.
The two approaches to entering multiple file names in Windows are shown in the following
one liner examples (neither example has any Perl code in them).
perl -e " " input.txt # single file name
perl -e " " input1.txt input2.txt # multiple file names (no commas)
To read each line of the supplied filenames, just use the <> operator, as in the
following examples.
perl -e "print <>" input.txt # single file printed
perl -e "print <>" input1.txt input2.txt # both files printed
Once all the lines of a file in the list are read, Perl continues to read lines in
any additional files.
The command line content following the one liner code is available to the code via
the array @ARGV, thus providing access to the individual names supplied on the
command line. In the above example, the array @ARGV contains two elements,
'input1.txt' and 'input2.txt'.
Using File Wildcards
Unfortunately, using wildcards on the command line in Windows isn't supported. The problem
is that Perl expects the command line to expand the wildcard list. Unix does this but
Windows does not. The following example, which shows the preferred way to enter
multiple file names, works in Unix but not in Windows.
perl - e "print <>" *.txt
Fortunately there are several ways to use wildcards with Perl one liners in Windows,
as shown in the following examples.
perl -e "for (<*.txt>) {print <>} # <> will expand wildcards
perl -e "for (`dir /b *.txt`) {print <>}" # backtick runs dir command
perl -e "for (glob '*.txt') {print <>}" # Perl glob supports wildcards
dir /b *.txt | perl -e "print <>" # piping feeds filenames to script
The first 3 approaches create lists of file names which are used in for loops
to print the file content. The last example using the DOS piping command to
send the file names to the Perl script.
Redirecting Output
When running any Perl script that prints its output to the screen you can use
redirection to send the screen output to a file, as the following examples
show.
perl -e " print 'hello'" > output.txt # create output.txt
perl -e " print 'hello'" >> output.txt # append to output.txt
The > redirection symbol creates a file and fills it with the output
of the Perl one liners. The >> redirection symbol opens the output file
and appends the output of the of the Perl script.
Piped Inputs
When running a Perl script you may send the output of any shell command to
a Perl script using the | piping command, as the following example shows.
dir /b *.jpg | perl -e "print <>" # prints content of *.jpg files
type input.txt | perl -e "print <>" # prints content of input.txt
The piping symbol | is used to send the output of a shell command to the
Perl script. In this case the <> symbols read STDIN, which is where the
piping input is fed to the one liner.
Multi-Script One Liners
Although one liner commands are the topic of this tutorial, the -e switch can
actually be used more than once to execute multiple Perl scripts, as in the
following example.
perl -e "print 5;" -e "print 6" # two scripts, one for each -e
This simple example will print "56", resulting from the execution of
the two separate Perl scripts. Note that the semicolon is required in
all Perl statements except the last one, hence the semicolon in "print 5;"
Variable values defined in a -e switch carry over to the Perl code in the
next -e switch For example, the following script correctly prints the values
of $a as 5.
perl -e "$a=5;" -e "print $a" # prints "5"
Quote Characters
The number one difference between Windows and Unix one liners is that Windows
must use the double quote, whereas Unix can use single quotes. You can use single
quotes for inner quotes within the code, but when interpolation is needed you'll
need to use the qq// double quote operator, which is recognized by Windows.
perl -e "$a = 'Hello World'; print qq/$a/" # prints "Hello World"
perl -e "$a = 'Hello World'; print q/$a/" # prints "Hello World"
The first example uses the qq// double quote to ensure that $a is interpolated
to print "Hello World". The second example uses the q// single quote, which does
not interpolate and will print the literal characters "$a".
Remember to separate each additional code statement with a semicolon. Only the
very last statement does not need a semicolon.
Perl scripts can also be written using other quoting operator delimiters. See perldoc for
more details, but here's an example where the {} symbols are used in place of the //
characters.
perl -e "$a=5;print q{single quotes}.qq{double quotes $a}"
Newline Character
A second confusion between Windows and Unix is the newline character. In Unix text
lines are separated by 0D - a single character, the carriage return. In Windows,
text lines are separated by 0D0A - two characters, the carrage return and line feed.
The problem for Windows users is that many Perl functions assume that a newline is
a single character. For example, the Perl length function incorrectly reports 0D0A
as a single character.
There's no single solution to the problem. I haven't gone through every function
to see how each handles newlines, nor am I aware of a listing which provides a
summary of functions/issues.
What I do have is the following summary information to help understand how
Windows handles the newline (OD0A) characters.
DOS files use CR-LF as a newline. Unix uses only the CR.
In Windows, CR is 13 (dec) is 0D (hex)
In Windows, LF is 10 (dec) is 0A (hex)
In Windows, print \n puts 0D0A in a file
In Windows, print \r put 0D in a file
In Windows, print \n\r puts 0D0A0D in a file
In Windows, s/\n/a/ replaces 0D0A with 'a'
In Windows, s/\r/a/ replaces 0A with 'a' (ignores 0D0A pairs)
In Windows, s/\n\r/a/ replaces 0D0A0D with 'a'
In Windows, s/a/\n/ replaces 'a' with 0D0A
In Windows, s/a/\r/ replaces 'a' with 0D
In Windows, s/a/\n\r/ replaces 'a' with 0D0A0D
Switch Summary
In addition to the -e switch Perl provides several other switches that are useful in
creating one liners. You can see the full list of Perl switches by typing in "Perl -h".
Switches may be used separately. Switches may also be combined unless a switch requires
arguments. If a switch requiring an argument is combined with other switches,
Perl will confuse the adjoining switch letters as the argument of the preceding
switch.
Some valid and invalid switch combinations are shown in the next examples.
perl -p -e "print 'Hello' " # valid - switches listed separately
perl -pe "print 'Hello' " # valid - switches combined
perl -ipe "print 'Hello' " # invalid - because -i requires argument
Not all of Perl's command line switches are equally useful in creating one
liners. Here is a summary of the most frequently used switches. A more detailed
description of using each switch is provided in the next section.
| -a | autosplits input into @F array (whitespace default can be changed)
| | -e program | indicates that Perl statements will be supplied on the command line
| | -F/pattern/ | changes the pattern input is split on with -a
| | -i/extension | operates on files in-place, with optional backup via -i.bak
| | -l | handles newlines
| | -M | M loads Perl module (examples: File::Slurp or IO::All)
| | -n | loops through input, without printing anything
| | -0[octal] | (a zero) specifies the input record separator.
| | -p | loops through input @ARG, printing each line of input
|
Additional Switch Explanations
Here are additional details on using some of the more useful switches.
The -n, -p and -i are most commonly used, and are discussed first. The
-a, -F, -M, -O and -l are less commonly used and are described next.
-p Switch - Looping Through a File
The -p switch executes the one liner code in a loop, once for each line of
text from the input files, printing each input line.
perl -pe "s/\s+//g;" input.txt
Removes spaces from each line of input.txt, prints results
The -p switch works by having Perl put the code "s/\s+//g" into the following
loop:
while (<>) {
... the code is put here
} continue {
print or die "-p destination: $!\n";
}
This loop reads each line of all input files, putting the content in $_. The
one liner code is then executed for each line (each value of $_). Then the
resulting value of $_ is printed.
Since most Perl functions operate on $_ by default, this approach can simplify
much of the code used in the one liner.
-n Switch - Looping Through a File
The -n switch does the same thing as the -p switch, except that it does
not print each line.
perl -ne "s/\s+//g;" input.txt
Removes spaces from each line of input.txt, does not print results
The -n is used when printing each line is not desired, or where a custom
print function is needed.
-i Switch - Inplace Editing of Input File
A file can be edited in place using the -i switch. In Windows the -i
switch must be used with an extension, such as i.bak. The original file
will be backed up using the supplied extension.
perl -i.old -pe "s/\s+//g" input.txt
Removes all spaces using s/\s+//g
i.old specifies backup extension of .old (input.txt.old)
-p loops through the lines of input.txt
-p also prints $_ after changes are made
Use this with caution!. If you execute the command twice, you've may
have overwritten your backups with the changed versions from the first run.
-a and -F Switches: Autosplitting of Input Records
The '-a' directs Perl to split each line from STDIN and to put the result
into the array @F. This is particularly useful when files are formatted
as columns of data (each column will be in a position of the array).
perl -nae "print $F[2], \n" input.txt
prints out only the 3rd column of data in each line
-n loops through the lines of input.txt
input.txt lines are placed in $_
-a split $_ into @F. $F[2] is the 3rd element of the array
The -F switch can be use to define an alternate delimiter for splitting input lines.
The -F format can define a literal string, such as -F":" or the format can be a
pattern such as -F/pattern/.
-l Switch - Line processing
The -l switch chomps each input record from STDIN and sets the output record
delimiter. The output record delimiter is kept in the special variable $\ and
has the default value of an empty string.
Used with no argument, the -l switch sets the output record separator ($\) to the
value of the input record separator, which is kept in the special variable $/ and
whose default value is a newline.
With no argument, the -l switch simply means that a newline is added to each print
statement, simplifying the one liner code needed to print lines of data.
perl -le "print 1; print 2" # '1' on first line, '2' on next line
perl -lpe "s/\s+//g" input.txt
replaces all spaces with an empty string using s/\s+//g
-p loops through the lines of input.txt
-p prints value of $_, after it is modified by the one liner code
-l (no argument) forces -p to add $_ to the print statement
-M Switch - Using Modules
The -M switch loads a module and makes it available for the one liner code.
-O Switch:
The -0 switch uses an argument to set the value of the input record separator,
which is kept in the special variable $/.
It is very useful if you want to read a full paragraph or a full file into a
single string. It also lets you define the end of records with a character other
than a newline (this might apply in the case of custom database formats).
The special value of -00 (same as $/="") reads paragraphs and the special value
of -0777 (same as $/=undef) reads the entire file into a single string (called
file slurp mode).
Converting One Liners to Full Scripts
To convert one liners into full Perl scripts requires more than simply copying
the one liners into a text file. Here are some tips on making the conversion.
Newline handling
To use the -l switch, simply use it on the shebang line of your Perl script.
#!/usr/bin/perl -l
Looping over input (-p or -n)
The looping code must be manually entered into the full script, as in the following
example. Use the print statement for -p, but not for -n.
while (<>) {
... the code is put here
} continue {
print
}
In Place Editing
To convert the -i in-place option, simply loop through each file name
found in the array @ARGV, opening/writing/close files as needed to match
the results of your one liner code.
The following code shows a straightforward approach to opening each file
and reading it's lines, including backing up the original.
@ARGV=('input1.txt','input2.txt'); # set file names
foreach (@ARGV) { # foreach to loop thru files
open(IN,$_); # open input file
open(OUT,"> NEW.$_"; # open output file
foreach () { # loop thru all lines
print OUT; # your code goes here
}
close IN; # close input file
close OUT; # close output file
rename $_, "$_.BAK" # rename original as backup
rename "NEW.$_", $_ # rename new as original
}
One Liner Links
These are some of the links I visited while preparing this tutorial on one liners.
If you have any suggestions or corrections, please let me know.
|