Reputation: 825
I have the following script that takes in an input file, output file and replaces the string in the input file with some other string and writes out the output file.
I want to change the script to traverse through a directory of files i.e. instead of prompting for input and output files, the script should take as argument a directory path such as C:\temp\allFilesTobeReplaced\ and search for a string x and replace it with y for all files under that directory path and write out the same files.
How do I do this?
Thanks.
$file=$ARGV[0];
open(INFO,$file);
@lines=<INFO>;
print @lines;
open(INFO,">c:/filelist.txt");
foreach $file (@lines){
#print "$file\n";
print INFO "$file";
}
#print "Input file name: ";
#chomp($infilename = <STDIN>);
if ($ARGV[0]){
$file= $ARGV[0]
}
print "Output file name: ";
chomp($outfilename = <STDIN>);
print "Search string: ";
chomp($search = <STDIN>);
print "Replacement string: ";
chomp($replace = <STDIN>);
open(INFO,$file);
@lines=<INFO>;
open(OUT,">$outfilename") || die "cannot create $outfilename: $!";
foreach $file (@lines){
# read a line from file IN into $_
s/$search/$replace/g; # change the lines
print OUT $_; # print that line to file OUT
}
close(IN);
close(OUT);
Upvotes: 6
Views: 12016
Reputation: 87
perl -pi -e 's#OLD#NEW#g' filename. You can replace filename with the pattern that suits your file list.
Upvotes: -1
Reputation: 37440
You can do this with the -i param:
Just process all the files as normal, but include -i.bak:
#!/usr/bin/perl -i.bak
while ( <> ) {
s/before/after/;
print;
}
This should process each file, and rename the original to original.bak And of course you can do it as a one-liner as mentioned by @Jamie Cook
Upvotes: 2
Reputation: 4515
I know you can use a simple Perl one-liner from the command line, where filename can be a single filename or a list of filenames. You could probably combine this with bgy's answer to get the desired effect:
perl -pi -e 's/original string/new string/' filename
And I know it's trite but this sounds a lot like sed, if you can use gnu tools:
for i in `find ./allFilesTobeReplaced`; do sed -i s/original string/new string/g $i; done
Upvotes: 1
Reputation: 47585
Try this
#!/usr/bin/perl -w
@files = <*>;
foreach $file (@files) {
print $file . '\n';
}
Take also a look to glob in Perl:
Upvotes: 1
Reputation: 7831
The use of the perl single liner
perl -pi -e 's/original string/new string/' filename
can be combined with File::Find
, to give the following single script (this is a template I use for many such operations).
use File::Find;
# search for files down a directory hierarchy ('.' taken for this example)
find(\&wanted, ".");
sub wanted
{
if (-f $_)
{
# for the files we are interested in call edit_file().
edit_file($_);
}
}
sub edit_file
{
my ($filename) = @_;
# you can re-create the one-liner above by localizing @ARGV as the list of
# files the <> will process, and localizing $^I as the name of the backup file.
local (@ARGV) = ($filename);
local($^I) = '.bak';
while (<>)
{
s/original string/new string/g;
}
continue
{
print;
}
}
Upvotes: 12