#!/usr/bin/perl
#
# Script to replace strings in multiple files.


use strict;
use warnings;

my $directory = $ARGV[0];
my $patternfile = $ARGV[1];
my (%pattern, @filelist);

usage() if ($directory eq "");
usage() if ($patternfile eq "");

read_pattern($patternfile);
scan_files($directory);

#--------------------------------------------------------------------------

sub usage
  {
  print qq~ 
  Script to replace strings in multiple files.
 
  Usage: replace.pl <directory> <pattern_file>

  <directory>     is the source of the directory tree
  <pattern_file>  is the file containing the pattern to be be replaced.

   Example: replace.pl /home/foo/bar /temp/pattern.txt

  Old string and the new string are enclosed in delimiters, which
  must not appear in the strings. Example:
    /oldpattern/newpattern/
    +/local/foo/+/local/bar/+
    |something|anything|
  ~;
  exit 1;
  }  

#--------------------------------------------------------------------------

sub  read_pattern 
  {
  my $patternfile = shift;
  my ($delim, $line);
  %pattern = ();
  if (-f $patternfile) 
    {
    open(PAT,"<", $patternfile) || die "Cannot read $patternfile: $!\n"; 
    while ($line = <PAT>) 
      {
      chomp($line);
      # first character --> delimiter
      $delim = substr($line,0,1);
      $line = substr($line,1);
      # delete last character (also delimiter)
      chop($line);
      if($delim && $line)
        {
        # find delimiter in $line
        my $pos = index($line,$delim);
        # split $line
        my $old = substr($line,0,$pos);
        my $new = substr($line,$pos+1);
        $pattern{$old} = $new;
        }
      }
    close PAT;
    }
  }

#--------------------------------------------------------------------------

sub  scan_files 
  {
  my $scandir = shift;
  my ($list);
  opendir(DIR,$scandir) || warn "Cannot opendir $scandir: $!\n";
  my @scandirs = grep {!(/^\./) && -d "$scandir/$_"} readdir(DIR);
  rewinddir(DIR);
  my @files = grep {!(/^\./) && -f "$scandir/$_"} readdir(DIR);
  closedir (DIR);
  for $list (0..$#scandirs) 
    { scan_files($scandir."/".$scandirs[$list]); }
  for $list (0..$#files) 
    {
    next if ($files[$list] =~ /\.gif|\.jpeg|\.jpg/);
    replacepattern("$scandir/$files[$list]");
    }
  }

#--------------------------------------------------------------------------

sub replacepattern 
  {
	my $source = shift;
	my @new = ();
	my ($line, $string);
	print "Processing $source ...\n";
  open (FILE,"<", $source) || die "Cannot open $source: $!.";
  my @file = <FILE>;
  close FILE;
  for $line (@file) 
    {
	  for $string (keys %pattern)
	    { $line =~ s/\Q$string\E/$pattern{$string}/gs; }
    push(@new,$line);
    }
  open (FILE,">", $source) || die "Cannot open $source: $!.";
  print FILE @new;
  close FILE;
  }
