If you are going to worry about Perl, why not just do your best and write a (short) Perl program to do this for you?
Thus, you do not pass it between the shell and your program, and you have something more universal and can work on several operating systems.
#!/usr/bin/env perl <-- Not needed for Windows, but tradition rules use strict; use warnings; use feature qw(say); use autodie; # Turns file operations into exception based programming use File::Find; # Your friend use File::Copy; # For the "move" command # You could use Getopt::Long, but let go with this for now: # Usage = mungestrings.pl <from> <to> [<dir>] # Default dir is current # my $from_string = shift; my $to_string = shift; my $directory = shift; $from_string = quotemeta $from_string; # If you don't want to use regular expressions $directory = "." if not defined $directory; # # Find the files you want to operate on # my @files; find( sub { return unless -f; # Files only return unless /\.txt$/ # Name must end in ".txt" push @files, $File::Find::name; }, $directory ); # # Now let go through those files and replace the contents # for my $file ( @files ) { open my $input_fh, "<", $file; open my $output_fh, ">" "$file.tmp"; for my $line ( <$input_fh> ) { $line =~ s/$from_string/$to_string/g; print ${output_fh} $line; } # # Contents been replaced move temp file over original # close $input_fh; close $output_fh; move "$file.tmp", $file; }
I use File::Find to collect all the files that I want to modify in my @files array. I could put all this in the find routine:
find(\&wanted, $directory); sub wanted { return unless -f; return unless /\.txt/;
The entire program is in the wanted routine in this way. This is more efficient because I now replace when I find files. No need to go through first, find files, and then perform a replacement. However, it looks like a bad design to me.
You can also delete your entire file into an array without scrolling it first:
open my $input_fh, "<", $file; @input_file = <$input_fh>;
Now you can use grep to check if there is something that needs replacing:
if ( grep { $from_string } @input_file ) {
This is more efficient (there is no need to perform a replacement unless this file contains the string you are looking for). However, it takes up memory (the entire file must be in memory at a time), and don't let one line fool you. The entire file is still read into this array one line at a time, as if you had completed the entire loop.
File::Find and File::Copy are standard Perl modules, so all Perl installations have them.