Softpanorama
May the source be with you, but remember the KISS principle ;-)

Contents Bulletin Latest Last year Top visited Scriptorama

Perl One Liners

News

Perl as a command line tool

Recommended Books Recommended Links

Perlrun man page

Debugging
Perl html transformations Quotes History and philosophy Tips Humor Etc

Perl one-liners are important part of any Perl programmer arsenal as well as any system administrator arsenal. They also form an important stage in learning Perl by system administrators, the stage on which awk scripts can be replaced with Perl one-liners. Remender the following Perl options used in oneliners (see Perl as a command line tool for more information

Some one-liners convert Perl into a useful command line utility (see Perl as a command line tool for additional information), for example:

  1. Replace a pattern pattern1 with another (pattern2)  globally inside the file and create a backup
    perl -i.bak -pe 's/pattern1/pattern2/g' inputFile
  2. unix2dos (conversion from Unix to Windows format; useful on SLES 10 and SLES 11 as it does not include it by default):
    perl -i.bak -pe 's/\n/\r\n/' filename 
  3. Select only lines between  a pattern pattern1 and pattern2
    perl -i.old -ne 'print unless /pattern1/ .. /pattern2/' filename
    for example
    perl -i.old -ne 'print unless /^START$/ .. /^END$/' filename
  4. Print file with line numbers
    perl -ne '$i++;print"$i\t$_";' filename
  5. Print balance of quotes in each line (useful for finding missing quotes in Perl and other scripts)
    perl -ne '@F=split;for $s (@F){ $j++ if $s eq q(")}; $i++;print"$i\t$j\t$_";' filename
  6. Emulation of Unix cut utility in Perl. Option -a ( autosplit mode) converts each line into array @F. The pattern for splitting a whitespace (space or \t) and unlike cut it accommodates consecutive spaces of \t mixes with spaces.   Here's a simple one-line script that will print out the fourth word of every line, but also skip any line beginning with a # because it's a comment line.

    perl -naF 'next if /^#/; print "$F[3]\n"'

    Here is example on how to print first and the second from the last columns:

    perl -lane 'print "$F[0]:$F[-2]\n"'

Tom Christiansen examples

Here is example from Tom Christiansen one liners which shows how to print each line with its characters backwards:

        perl -nle 'print scalar reverse $_' file1 file2 file3 ....

Matz Kindahl - Collection of Perl programs

These are one liners that might be of use. Some of them are from the net and some are one that I have had to use for some simple task. If Perl 5 is required, the perl5 is used.
perl -ne '$n += $_; print $n if eof'
perl5 -ne '$n += $_; END { print "$n\n" }' 
To sum numbers on a stream, where each number appears on a line by itself. That kind of output is what you get from cut(1), if you cut out a numerical field from an output. There is also a C program called sigma that does this faster.

 

perl5 -pe 's/(\w)(.*)$/\U$1\L$2/'
perl5 -pe 's/\w.+/\u\L$&/'
To capitalize the first letter on the line and convert the other letters to small case. The last one is much nicer, and also faster.

 

perl -e 'dbmopen(%H,".vacation",0666);printf("%-50s: %s\n",$K,scalar(localtime(unpack("L",$V)))while($K,$V)=each(%H)'
Well, it is a one-liner. :)
You can use it to examine who wrote you a letter while you were on vacation. It examines the file that vacation(1) produces.

 

perl5 -p000e 'tr/ \t\n\r/ /;s/(.{50,72})\s/$1\n/g;$_.="\n"x2'
This piece will read paragraphs from the standard input and reformat them in such a manner that every line is between 50 and 72 characters wide. It will only break a line at a whitespace and not in the middle of a word.

 

perl5 -pe 's#\w+#ucfirst lc reverse $&#eg'
This piece will read lines from the standard input and transform them into the Zafir language used by Zafirs troops, i.e. "Long Live Zafir!" becomes "Gnol Evil Rifaz!" (for some reason they always talk using capital letters).
Andrew Johnson and I posted slightly different versions, and we both split the string unnecessarily. This one avoids splitting the string.

 

perl -pe '$_ = " $_ "; tr/ \t/ /s; $_ = substr($_,1,-1)'
This piece will remove spaces at the beginning and end of a line and squeeze all other sequences of spaces into one single space.
This was one of the "challenges" from comp.lang.perl.misc that occurs frequently; I am just unable to resist those. :)

Tom Christiansen  once posted a list of one line perl programs to do many common  command-line tasks. 

# simplest one-liner program:

perl -e 'print "hello world!\n"' 

   # add first and penultimate columns
   perl -lane 'print $F[0] + $F[-2]'

   # print just lines 15 to 17
   perl -ne 'print if 15 .. 17' *.pod

   # in-place edit of *.c files changing all foo to bar
   perl -p -i.bak -e 's/\bfoo\b/bar/g' *.c

   # command-line that prints the first 50 lines (cheaply)
   perl -pe 'exit if $. > 50' f1 f2 f3 ...

   # delete first 10 lines
   perl -i.old -ne 'print unless 1 .. 10' foo.txt

   # change all the isolated oldvar occurrences to newvar
   perl -i.old -pe 's{\boldvar\b}{newvar}g' *.[chy]

   # command-line that reverses the whole file by lines
   perl -e 'print reverse <>' file1 file2 file3 ....

   # find palindromes
   perl -lne 'print if $_ eq reverse' /usr/dict/words

   # command-line that reverse all the bytes in a file
   perl -0777e 'print scalar reverse <>' f1 f2 f3 ...

   # command-line that reverses the whole file by paragraphs
   perl -00 -e 'print reverse <>' file1 file2 file3 ....

   # increment all numbers found in these files
   perl i.tiny -pe 's/(\d+)/ 1 + $1 /ge' file1 file2 ....

   # command-line that shows each line with its characters backwards
   perl -nle 'print scalar reverse $_' file1 file2 file3 ....

   # delete all but lines between START and END
   perl -i.old -ne 'print unless /^START$/ .. /^END$/' foo.txt

   # binary edit (careful!)
   perl -i.bak -pe 's/Mozilla/Slopoke/g' /usr/local/bin/netscape

   # look for dup words
   perl -0777 -ne 'print "$.: doubled $_\n" while /\b(\w+)\b\s+\b\1\b/gi'

   # command-line that prints the last 50 lines (expensively)
   perl -e 'lines = <>; print @@lines[ $#lines .. $#lines-50' f1 f2 f3 ...



Old News ;-)

[Jan 18, 2012] I am looking forward to learn perl

LinkedIn

Q: Hi, I'm looking forward to learn perl, I m a systems administrator ( unix ) .I'm intrested in an online course, any recommendations would be highly appreciated. Syed

A: I used to teach sysadmins Perl in corporate environment and I can tell you that the main danger of learning Perl for system administrator is overcomplexity that many Perl books blatantly sell. In this sense anything written by Randal L. Schwartz is suspect and Learning Perl is a horrible book to start. I wonder how many sysadmins dropped Perl after trying to learn from this book

See http://www.softpanorama.org/Bookshelf/perl.shtml

It might be that the best way is to try first to replace awk in your scripts with Perl. And only then gradually start writing full-blown Perl scripts. For inspiration you can look collection on Perl one-liners but please beware that some (many) of them are way too clever to be useful. Useless overcomplexity rules here too.

I would also recommend to avoid OO features on Perl that many books oversell. A lot can be done using regular Algol-style programming with subroutines and by translating awk into Perl. OO has it uses but like many other programming paradigms it is oversold.

Perl is very well integrated in Unix (better then any of the competitors) and due to this it opens for sysadmin levels of productivity simply incomparable with those levels that are achievable using shell. You can automate a lot of routine work and enhance existing monitoring systems and such with ease if you know Perl well.

[Jan 18, 2012] Famous Perl One-Liners Explained, Part VII Handy Regular Expressions

www.catonmat.net
109. Match something that looks like an IP address.
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/

This regex doesn't guarantee that the thing that got matched is in fact a valid IP. All it does is match something that looks like an IP. It matches a number followed by a dot four times. For example, it matches a valid IP 81.198.240.140 and it also matches an invalid IP such as 923.844.1.999.

Here is how it works. The ^ at the beginning of regex is an anchor that matches the beginning of string. Next \d{1,3} matches one, two or three consecutive digits. The \. matches a dot. The $ at the end is an anchor that matches the end of the string. It's important to use both ^ and $ anchors, otherwise strings like foo213.3.1.2bar would also match.

This regex can be simplified by grouping the first three repeated \d{1,3}\. expressions:

/^(\d{1,3}\.){3}\d{1,3}$/

 

119. Replace all <b> tags with <strong>
$html =~ s|<(/)?b>|<$1strong>|g

Here I assume that the HTML is in variable $html. Next the <(/)?b> matches the opening and closing <b> tags, captures the optional closing tag slash in group $1 and then replaces the matched tag with either <strong> or </strong>, depending on if it was an opening or closing tag.

[May 21, 2006] Matz Kindahl - Collection of Perl programs

These are one liners that might be of use. Some of them are from the net and some are one that I have had to use for some simple task. If Perl 5 is required, the perl5 is used.
perl -ne '$n += $_; print $n if eof'
perl5 -ne '$n += $_; END { print "$n\n" }'
To sum numbers on a stream, where each number appears on a line by itself. That kind of output is what you get from cut(1), if you cut out a numerical field from an output. There is also a C program called sigma that does this faster.
 
perl5 -pe 's/(\w)(.*)$/\U$1\L$2/'
perl5 -pe 's/\w.+/\u\L$&/'
To capitalize the first letter on the line and convert the other letters to small case. The last one is much nicer, and also faster.
 
perl -e 'dbmopen(%H,".vacation",0666);printf("%-50s: %s\n",$K,scalar(localtime(unpack("L",$V)))while($K,$V)=each(%H)'
Well, it is a one-liner. :)
You can use it to examine who wrote you a letter while you were on vacation. It examines the file that vacation(1) produces.

 

perl5 -p000e 'tr/ \t\n\r/ /;s/(.{50,72})\s/$1\n/g;$_.="\n"x2'
This piece will read paragraphs from the standard input and reformat them in such a manner that every line is between 50 and 72 characters wide. It will only break a line at a whitespace and not in the middle of a word.

 

perl5 -pe 's#\w+#ucfirst lc reverse $&#eg'
This piece will read lines from the standard input and transform them into the Zafir language used by Zafirs troops, i.e. "Long Live Zafir!" becomes "Gnol Evil Rifaz!" (for some reason they always talk using capital letters).
Andrew Johnson and I posted slightly different versions, and we both split the string unnecessarily. This one avoids splitting the string.

 

perl -pe '$_ = " $_ "; tr/ \t/ /s; $_ = substr($_,1,-1)'
This piece will remove spaces at the beginning and end of a line and squeeze all other sequences of spaces into one single space.
This was one of the "challenges" from comp.lang.perl.misc that occurs frequently; I am just unable to resist those. :)

[Nov 15, 2004] Perl one-liners for the bioinformatician

In the Perl spirit of "Programming is fun", here are some one-liners that might be actually useful. Please mail me yours, the best one-liner writer wins a Perl magnetic poetry kit. Contest closes July 31st, 2000. Please note that it is me personally running this competition, not NRCC, CBR or IMB. "Best" is subjective, and will be determined by an open vote.

Take a multiple sequence FASTA sequence file and print the non-redundant subset with the description lines for identical sequence concatenated with ;'s. Not a small one-liner, but close enough.

perl -ne 'BEGIN{$/=">";$"=";"}($d,$_)=/(.*?)\n(.+?)>?$/s;push @{$h{lc()}},$d if$_;END{for(keys%h){print">@{$h{$_}}$_"}}' filename

Split a multi-sequence FastA file into individual files named after their description lines.

perl -ne 'BEGIN{$/=">"}if(/^\s*(\S+)/){open(F,">$1")||warn"$1 write failed:$!\n";chomp;print F ">", $_}'

Take a blast output and print all of the gi's matched, one per line.

perl -pe 'next unless ($_) = /^>gi\|(\d+)/;$_.="\n"' filename

Filter all repeats of length 4 or greater from a FASTA input file. This one is thanks to Lincoln Stein and Gustavo Glusman's discussions on the bio-perl mailing list.

perl -pe 'BEGIN{$_=<>;print;undef$/}s/((.+?)\2{3,})/"N"x length$1/eg' filename

[Oct 8,  2004] Re perl oneliner for grep

By : anonymous ( Fri Oct 8 01:39:43 2004 )

Try using the -P option with grep. This enables perl regular expressions in grep e.g.
grep -P "\S+\s+\S+" file

[Sep 17, 2004] chmod all files in a directory

By : anonymous ( Fri Sep 17 20:22:02 2004 )

perl -e 'chmod 0000 $_ while <*>'

[Mar 16, 2004] Comma-delimit your output 

By : anonymous ( Tue Mar 16 15:05:27 2004 )

perl -wne 'BEGIN{$" = ","} @fields = split/\s+/; print "@fields\n";'  

 

Recommended Links

One-liner program - Wikipedia, the free encyclopedia

Famous Perl One-Liners Explained, Part I File Spacing

Famous Perl One-Liners Explained, Part VII Handy Regular Expressions

one-liners by Jeff Bay,

Essential One-Liners

Perl Scripts And One Liners - www.socher.org

TPJ One Liners - The Perl Journal, Fall 1998

Perl tricks by Neil Kandalgaonkar



Copyright © 1996-2012 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine. This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

Disclaimer:

Last updated: March 07, 2012