#!/usr/bin/perl -w # Script to make text replacements to a list of files # # The author of this script makes no warranty, # express or implied, that this script will # do anything useful at all, and any use # of it is entirely at your own risk. # # by Lev Koszegi 4/10/2006 use File::Copy; use File::Basename; use Cwd; usage() unless $#ARGV == 1; #Require two arguments (list file & pattern file) my (@files, @patterns); my ($pattern, $filename); my $now = time; my $dir = cwd; open FILE_LIST, $ARGV[0] or die "Cannot open file list: $!"; chomp(@files =); #Test the lines of FILE_LIST to make sure files exist; #if not, note which one is bad and die. foreach $filename (@files) { die "Invalid file name ($filename): $!" unless -e $filename; } close FILE_LIST; open PATFILE, $ARGV[1] or die "Cannot open pattern file: $!"; #Test the pattern file to make sure it looks okay, or die. chomp(@patterns = ); foreach $pattern (@patterns) { #Pattern must begin with a forward slash, contain exactly three #unescaped forward slashes, and end with same plus optional g and/or i. unless ($pattern =~ /^\/.*[^\\]\/.*[^\\]\/(g|i|gi|ig)?$/) { die " : bad pattern: $@"; } #Create the substitution commands. $pattern = 's' . $pattern; } close PATFILE; #Create backup directory, timestamped to make it unique. my $bakdir = "bak_${now}"; mkdir $bakdir, 0755 or die "Cannot create archive directory: $!"; my $tarFile = $bakdir . '/' . "bak.tar"; my $logfile = $bakdir . '/' . "logfile"; #Create log file open LOG, "> $logfile" or die "Cannot create logfile: $!"; select LOG; $| = 1; # Don't keep LOG entries sitting in the buffer. select STDOUT; #Tarball the files to archive current state !(system "tar", "chvlf", $tarFile, "-I", $ARGV[0]) or die "Cannot create backup archive!"; print LOG "Created archive OK.\n"; !(system "gzip", $tarFile) or print LOG "Cannot compress archive; proceeding anyway.\n"; #Loop through each file and make the edit(s) foreach $filename (@files) { #Copy contents of file to a temporary work file. my $wkfile = $bakdir . '/' . basename $filename; copy($filename, $wkfile) or die "Cannot copy ${filename}: $!"; open(FILE2CHANGE, "<$wkfile") or die "Cannot open ${wkfile} for reading: $!"; open(UPDATED, ">$filename") or die "Cannot open ${filename} for writing: $!"; while ( ) { #Run each substitution on the line. foreach $pattern (@patterns) { eval $pattern; } print UPDATED; } print LOG "Processed ${filename}\n"; close FILE2CHANGE; close UPDATED; unlink $wkfile; } close LOG; ################################### sub usage { die < Re: Edit a List of Filescreated: 2006-04-10 16:54:18A mixture of, mostly minor, stylistic issues:
use strict; use warnings;That mantra should come before you do anything else! Always! Regardless of projet size! No exceptions! Comprende?
(condition) or print "fail string";is cute, but
print "fail string" if condition;is clearer. In cases where the fail condition is non-zero it is even better to make it explicit:
print "fail string" if 0 != (condition);It is tempting to comment things that you have just learned, but that can lead to over commenting and make it harder to grok the flow of the code.
$var1 . 'string1' . "string2" is better written as "${var1}string1string2". Note the ${var1} usage to clarify where the variable name ends.
The block for while (
) { is not indented.
DWIM is Perl's answer to GödelRe^2: Edit a List of Filescreated: 2006-04-11 16:54:58Thanks!
I added use strict;, and fixed the indent problem. As for use warnings;, doesn't the "-w" in #!/usr/bin/perl -w do the same thing?
I don't have time right now, but I'll review the script and consider your other suggestions as well. I do appreciate it!
Re: Edit a List of Filescreated: 2006-04-11 00:03:38Thank you!A very useful script.
I would like to add something to my own version of this script:
Then this script could become a very powerful tool!
- > Log files should speak clear and simple. Those are tools to work with even if the user ignores what the script is doing. After some time, I might forget what was the script doing. When preparing logs for large number of processed files it is easier to read one or two lines clearly identified with each file.
- > Making a more expressive table of regexes that could load inside a hash with different extensions and another generic key that would apply to all files. That would be easy by just starting from a standard template with fields to fill in. (A kind of ini file where lines starting with # wouldn't count as values. And keys would start without any tab character)
- > Modules could make this script useful for any platform!
- Landlords production is only eaten by landlords...
- Wherever I lay my KNOPPIX disk, a new FREE LINUX nation could be established
Re^2: Edit a List of Filescreated: 2006-04-11 17:08:13Thanks for your comments, Chanio. I'm considering how to make the log file a little more clear and informative.
Your other suggestions sound good too, though they are more than I have time to figure out right now.
And you should certainly feel free to take it and modify it for your own use! Especially if you share what you did and why, so I can learn yet more.
perlmonks.org content © perlmonks.org and chanio, GrandFather, lev36
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03