I have a little script that iterates through a list of files and makes a substitution to lines matching a pattern. It writes the new version of the file over the old, after having saved the old with a .bak extension.
Here's the part that actually does the substitution:
#earlier in the script, we have created
#the array of files to edit, and named it @files
foreach my $filename (@files) {
my $backup = $filename . '.bak';
copy($filename, $backup)
unless -e $backup;
open(FILE2CHANGE, "<$backup");
open(UPDATED, ">$filename") or die "$filename: $!";
while () {
s/foo/bar/g;
print UPDATED;
}
close FILE2CHANGE;
close UPDATED;
}
To make this script more reusable, I would like to remove the substitution line (s/foo/bar/g) and, instead, have the script read one or more substitution commands from a separate file.
To wit, the substitution file might read:
s/foo/bar/g s/something/something else/
In which case, the script would read these lines and execute them both, upon each file. But I don't want this substitution file to be an executable script in itself; just a data file containing the lines to be used to make the substitution(s).
It's easy enough to read these lines into a array, but is there a way to then run the lines from the variable as if they were lines of code?
Of course, in an ideal world, the script should first make sure the substitution commands look valid, but I haven't even tried to wrap my head around that problem yet...
Thanks,
Lev
After Compline,
Zaxo
Not answering your immediate question, but a Perl idiom worth knowing is the edit inplace:
$ARGV = @files;
$^I = '.bak';
while (<>) {
# do something with each line of each file
# The original line contents is in $_
# print prints to the new version of the file
s/foo/bar/g;
print;
}
@ARGV = @files;??
-QM
--
Quantum Mechanics: The dreams stuff is made of
Thanks, GrandFather, but that brings up an interesting thing.
I liked your code because it was more elegant, so I switched mine to use Perl's edit inplace - but then noticed that the updated file no longer had the original owner.
My original script kept the original owner on the file, without having to 'chown' it back, and we do need to retain the original owners in this case.
Sorry, I'm a Windows user and don't generally notice that sort of issue. If no-one replies to the question buried in this thread, repost it as a SoPW in its own right.
perl -i.bak -pe "s/OrigTxt/SubsText/g" FileName1.txt FileName2.txtSo, instead of the "s" commands being in a separate file, you could just have a bunch of one-liners in the file, each one specific to the substitution you need. Cleaner, and more maintainable. Let perl do the work for you.
"For every complex problem, there is a simple answer ... and it is wrong." --H.L. Mencken
You can easily read the $match and $replace values from a file and it is less dangerous than using eval (who knows what someone might have put in that file you just eval-ed?)
CountZero
"If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
If you're worried about someone putting Bad Things in your data file, then you'd need to worry about ?{CODE} just as much as eval STRING.
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
CountZero
"If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
perlmonks.org content © perlmonks.org and CountZero, GrandFather, hardburn, lev36, NetWallah, QM, Zaxo
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03