Reputation: 341
I have written a perl code to get the source filename ,destination filename, pattern and replacement string.The below one is the code I have written.
chomp($input=<stdin>); #source file name.
open SRC, $input; #opening the file .
chomp($input=<stdin>); #destination file name.
open DES, ">>$input"; #opening the file.
chomp($pattern=<stdin>); #pattern to be matched.
chomp($replace=<stdin>); #replacement string.
while(<SRC>){
s/$pattern/$replace/g;
print DES $_;
}
I have written this code to replace the particular value in a file and store it in another file. As per the code if I have given the pattern " "(white space) and replacement string as \n ,it should give the output as follows.
Hai hello this for testing .
Hai
hello
this
for
testing
.
But it has given the output as follows.
hai\nhello\nthis\nis\nfor\ntesting\n.
Please help me to solve this problem.
Upvotes: 2
Views: 206
Reputation: 126722
Please, you must always use strict
and use warnings 'all'
at the top of every Perl program you write, end declare every variable with my
. You should also use lexical file handles and the three-parameter form of open
, and always check that a call to open
has succeeded. So
open DES, ">>$input"
should be more like
open my $des_fh, '>>', $input or die qq{Unable to open "$input" for appending: $!}
You could use eval
for this, but it's much cleaner and safer to use the String::Interpolate
module, which provides access to the code within perl that processes double-quoted strings. It exports The interpolate
function, which will correctly translate all variable references as well as any special characters like \n
or \t
It would look like this
use strict;
use warnings 'all';
use String::Interpolate 'interpolate';
chomp( my $in_file = <> );
open my $in_fh, '<', $in_file or die qq{Unable to open "$in_file" for input: $!};
chomp( my $out_file = <> );
open my $out_fh, '>>', $out_file or die qq{Unable to open "$out_file" for input: $!};
chomp( my $pattern = <> );
chomp( my $replace = <> );
$replace = interpolate($replace);
while ( <$in_fh> ) {
s/$pattern/$replace/g;
print $out_fh $_;
}
Note that you could enter the parameters on the command line instead of having your program prompt for them
use strict;
use warnings 'all';
use String::Interpolate 'interpolate';
my $pattern = shift;
my $replace = shift;
$replace = interpolate($replace);
print s/$pattern/$replace/gr while <>;
You would call this like so
$ perl replace.pl ' ' '\n' sample.txt
and you can redirect the output to a file in the normal way
$ perl replace.pl ' ' '\n' sample.txt > output.txt
Upvotes: 7
Reputation: 385655
I strongly recommend the functions provided by String::Substitution.
Replace
s/$pattern/$replace/g;
with
use String::Substitution qw( gsub_modify );
gsub_modify($_, $pattern, $replace);
This won't just handle \n
; it'll handle $1
too!
Notes:
There is a lot of advice to use eval EXPR
(sometimes disguised as /ee
), but this is very error-prone and dangerous.
In the past, I've provided solutions that use String::Interpolate, but the module provides an extremely weird interface.
Upvotes: 1