Undoubtedly one of the most frequent tasks a system administrator, or developer, faces involves making inline changes to a file or set of files. This can range from the very complex edit to the very trivial.
Let’s say you have a series of PHP pages in your web site that access your MySQL server. What happens if you need to change the name of your MySQL server? Would you go into each file individually, search for the line (or lines) of code to edit and save the file? This can be tedious, error-prone and time consuming.
The ’sed’ (string editor) command is often used to accomplish this, where sed is passed a file name and a regular expression for the string substitutions. Output from sed is sent to standard output (usually the terminal) which means that you must redirect it to another file and then copy the new file over the original. This effectively changes the original but requires a lot of excess steps. There’s got to be a better way, right? Yes, ‘perl’ can do it in one shot –
SysAdmin Mantra
A good sysadmin is a lazy sysadmin.
Enter ‘Perl Pie’
I forget who first introduced me to the concept of ‘perl -p -i -e’ (or ‘perl -pi -e’). This has become such a mainstay of my practice that I often mention it to people assuming that everyone knows of such things. Basically, ‘Perl Pie’ is a one-line perl program that does inline edits to your file given a regular expression (preserving file ownership and permissions — a topic that I didn’t discuss in the ’sed’ example above). The syntax should look familiar to anyone who’s used ’sed’ or regular expressions.
perl -p -i -e 's/original text string/replacement string' foo
Note: perl uses the same regex syntax as sed, making this an easy concept to remember
But Wait, I’ve got a ton of files to edit
There are numerous ways to accomplish editing multiple files, but they all share some basic principals:
- Find a list of files matching your change criteria
- With each file, apply the ‘Perl Pie’
Most GNU/Linux sysadmins are familiar with the Bash shell. Here’s a simple example that changes all of those PHP pages we talked about earlier. This example also involves the ‘find’ and ‘grep’ commands:
$ for filename in $( find . -type f -name '*.php' -exec grep -q '$db=OLDMYSQLSERVER' '{}' ';' -print );
do
perl -p -i -e 's/$db=OLDMYSQLSERVER/$db=NEWMYSQLSERVER/g' $filename
done
#1 by dhunter on August 3rd, 2007
Quote
Specifying an extension after the ‘-i’ option will save your old file with the extension.
perl -p -i.old -e ’s/original text string/replacement string’ foo
#2 by Joaquin Almstead on July 7th, 2012
Quote
Have you ever thought about writing an ebook or guest authoring on other blogs? I have a blog based on the same topics you discuss and would love to have you share some stories/information. I know my audience would value your work. If you are even remotely interested, feel free to shoot me an e mail.
#3 by vikram on July 13th, 2012
Quote
i want to replace a long string which has plus minus brace open close and alpha numeric words then how can i replace them in all the files ?
#4 by Gergo on January 24th, 2013
Quote
i think it is time for me to start learning pearl….