Replace Strings in Multiple Files

The best tool for replacing strings is Perl. It can even do it for multiple files. You don’t need to know much Perl to use the “Perl PIE” technique, that turns a potentially long script into a one-liner. I used it to start an SEO task on this site.

Meet the Perl -p -i -e

This following command replaces all occurrences of “yes” with “no” in all the files in this directory.
this

    perl -p -i -e "s/yes/no/g" *

-e means “the next word is a program”.

-i means “edit in place”. This option can also take an argument that will be appended as a file name extension.

-p means “iterate over the arguments, treating them like file names”.

You can also write it as:

    perl -pie

The command I was using: Google Analytics

I wanted to add Google Analytics to the old site’s pages, which were archived as HTML files.

 perl -p -i -e 's#<head>#<head><!-- Global site tag (gtag.js) - Google Analytics --><script async src="https://www.googletagmanager.com/gtag/js?id=UA-6577692-1"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag("js", new Date()); gtag("config", "UA-6577692-1");</script>#g'

That’s the regular Google Analytics code, except that all put into one line, and the single quotes are replaced with double quotes, so it’ll work on the command line.

Recursing Through Directories

I have hundreds of HTML pages to modify, so, I cannot list them all on the command line. Instead, I used the find command to
recurse through the directories. Here’s an example of that, without the perl command:

find . -name "*.html" -exec ls {} \;

find . means find files starting in this directory.

-name “*.html” means find only files that match this pattern.

-exec means run the following command on matched files.

Within an -exec, the {} pair is replaced with the filename. The -exec command is terminated with a semicolon (;), but we need to write it as \; so it’s escaped from the shell.

My final command replaced the ls stuff with the perl command:

find . -name "*.html" -exec perl -p -i -e 's#<head>#<head><!-- Global site tag (gtag.js) - Google Analytics --><script async src="https://www.googletagmanager.com/gtag/js?id=UA-6577692-1"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag("js", new Date()); gtag("config", "UA-6577692-1");</script>#g' "{}" \;

It took a few seconds to run, and it did the trick.

It took several minutes to test the code on some copies of the files, but once it worked, “boom”, and it was done.

Leave a Reply