Running and Debugging Perl
When we're searching and replacing the contents of a file, we usually don't want to produce a new, revised copy on standard output, but rather change the file as it stands. You might think of doing something like this:
>perl -pe 's/one/two/g' textfile.txt > textfile.txt
There's a problem with that though, as you'll know if you've tried it, it's quite possible that you'll completely lose the file. This is because (unless you're running in a shell that's smart enough to watch your back) the shell opens the file it's writing to first and then passes the filehandle to perl as standard output. Perl opens the file after this has taken place, but by this time, the original contents of the file have been wiped out.
To get around this yourself, you'd have to go through contortions like this:
>perl -pe 's/one/two/g' textfile.txt > textfile.new >mv textfile.new textfile.txt
The UNIX command mv is the same as the ren command in Windows: Both commands are used to rename files.
Perl provides you with a way to avoid this. The -i switch opens a temporary file and automatically replaces the file to be edited with the temporary file after processing. You can do what we want just like this:
>perl -pi -e 's/one/two/g' textfile.txt
Well, you might be able to – as it stands, you may find that this just returns the message:
Can't do inplace edit without backup
This happens because perl doesn't know how you want to name the temporary file. Notice though, that I separated -i from the -e switch: this is because -i takes an optional argument. Anything immediately following the -i will be treated as an extension to be added to the original filename as a name for the backup file. So, for instance:
>perl -pi.old -e 's/one/two/g' textfile.txt
will take in a file, textfile.txt, save it away as textfile.txt.old, and then replace every instance of 'one' with 'two' in textfile.txt.
If you need to load any modules from the command line, you can use the -M switch. For instance, to produce politically correct one-liners, we should really say something like this:
>perl -Mstrict -Mwarnings –e ...