Using perl for in-place search-and-replace

This post was written by eli on July 16, 2013
Posted Under: perl

To make a long story short:

$ perl -pi.bak -e 's/this/that/g' `find inhere/ -type f`

or to delete entire lines that contain a certain substring:

$ perl -pi.bak -e 's/^.*?RUNTIME_PARAM.(?:OUTPUT|SHARED)DIR.*?[\n\r]+//gm' $(find . -iname \*.xci)

This will create backup files. Yes, you want them. Really. Otherwise, in particular under Windows, errors like this may show up:

Can't do inplace edit on inhere/example.c: Permission denied.

This may look harmless, but in fact the target file ends up complete deleted. So don’t go just perl -pi -e. It may go horribly wrong.

Another thing to watch out for is having the .git subdirectory included in the “find” statement. In particular, “find .” may lead to this. Messing up the git repository is no fun.

The in-place execution runs separately on each line, so it’s not useful for replacing things that span across more than one line. In that case, a “full” perl script should be used. For example, in order to remove multiple blank lines from C sources,

$ for i in *.c *.h ; do perl -e 'local $/; $a=<>; $a=~s/\n{3,}/\n\n/g; print $a;' < $i > $; mv -f $ $i; done

This removes any occurrence of three or more newlines into two. It’s fine to have an empty line, but not more than one.

Add a Comment

required, use real name
required, will not be published
optional, your blog address