Hopefully this will work for you.
#! /usr/bin/env perl
use strict;
use warnings;
use 5.010;
use autodie;
my($in_file,$filter,$out_file);
if( @ARGV == 0 ){
die "Must have filter at least\n";
}elsif( @ARGV == 1 ){
($filter) = @ARGV;
}elsif( @ARGV >= 2 ){
($in_file,$filter) = @ARGV;
}else{
($in_file,$filter,$out_file) = @ARGV;
}
{
# autodie checks open() for errors
# so we don't have to
my($IN,$OUT);
if( defined $in_file ){
open $IN, '<', $in_file;
}else{
$IN = *STDIN{IO};
}
if( defined $out_file ){
open $OUT, '>', $out_file;
}else{
$OUT = *STDOUT{IO};
}
ProcessFiles($IN,$OUT,$filter);
close $OUT;
close $IN;
}
sub ProcessFilter{
my($filter,$str) = @_;
my @elem = grep {$_} split ' ', $str;
$filter =~ s/\$(?|(?:{(\d+)})|(\d+))/ $elem[$1-1] /eg;
return $filter;
}
sub ProcessFiles{
my($IN,$OUT,$filter) = @_;
while( my $line = <$IN> ){
chomp $line;
next unless $line;
$line = ProcessFilter($filter,$line);
say {$OUT} $line;
}
}
It is called in one of the following manners
perl program.pl <input-file> 'filter string' <output-file>
perl program.pl <input-file> 'filter string' # sends to STDOUT
perl program.pl 'filter string' # recieves from STDIN, sends to STDOUT
If called like this
program.pl FILE1 'stringaa ${1} stringbb $2'
it reads FILE1
and outputs:
stringaa ABC stringbb 123
stringaa DEF stringbb 456
stringaa GHI stringbb 111