Peeter Joot's (OLD) Blog.

Math, physics, perl, and programming obscurity.

perl -p … one of the handiest one liner commands

Posted by peeterjoot on July 29, 2009

Suppose you have a list of files:

$ cat r
/vbs/engn/include/sqlbgbc_inlines.h
/vbs/engn/include/sqlekrcb.h
/vbs/engn/sqb/sqlbenvi.C

that you want to make a systematic simple change to, replacing all instances of some pattern with another. For illustration purposes, suppose that replacement is a straight replacement of the simplest sort changing all instances of the variable type:

blah_t

to something else:

MyBlahType

Such a search and replace can be done in many ways. For one file it wouldn’t be unreasonable to run:

vim filename

then:

:%s/blah_t/MyBlahType/g
:wq

for multiple files, this isn’t the most convienent way (although you can do it with vim plus a command line for loop in a pinch using a vim command script if you really wanted to). An easier way is the following one liner:

perl -p -i -e 's/blah_t/MyBlahType/g' `cat r`

Let’s break this down. First is the `cat r` part. This presumes you are running in a unix shell where backquotes (not regular quotes like ”) mean “take the output of the back-quoted command and embed that in the new command”. This means the command above is equivalent to:

perl -p -i -e 's/blah_t/MyBlahType/g;' /vbs/engn/include/sqlbgbc_inlines.h /vbs/engn/include/sqlekrcb.h /vbs/engn/sqb/sqlbenvi.C

Next is the -i flag for the perl command. This specifies a suffix for a backup file. When no such file is specified (as here) then this means do an in-place modification of an existing file (something that’s particularily convienent if you are working with a version control system and if you have a recently checked out source file don’t have to worry as much about saving backups in case the search and replace goes wrong). If you wanted a backup, with suffix .bak, then replace -i with -i.bak (no spaces between -i and .bak).

The -e option says to treat the parameter as the entire perl program. By example, if you had the following small perl command in a file (say ./mySearchAndReplace):

$ cat ./mySearchAndReplace
s/blah_t/MyBlahType/g;

then the one liner above would also be equivalent to:

perl -p -i ./mySearchAndReplace /vbs/engn/include/sqlbgbc_inlines.h /vbs/engn/include/sqlekrcb.h /vbs/engn/sqb/sqlbenvi.C

The remaining worker option in the perl comand is the -p. This is really a convienence option and says to “wrap” the entire command (be that in a file or via -e) in a loop that processes standard input and outputs the results. You could do the same thing explicitly like so:

$ cat ./mySearchAndReplaceFilter
while (<>) # all lines from stdin
{
   s/blah_t/MyBlahType/g;
}

A command or script, such as sed, that takes all input from stdin and provides an altered stdout, is called a filter. In perl while (<$filehandle>) is the syntax to process all lines in an opened file, and nothing means the current default file (usually stdin). So a final decoding of the one liner is a command like:

perl -i ./mySearchAndReplaceFilter /vbs/engn/include/sqlbgbc_inlines.h /vbs/engn/include/sqlekrcb.h /vbs/engn/sqb/sqlbenvi.C
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: