Search code examples
perlperl-data-structures

perl parsing inserting new line and ^M


i am trying to modify a few strings in a file using perl by using the below logic..

open FILE1, "< /tmp/sam.dsl" //In read mode
open FILE2, "> /tmp/sam2.dsl" // Open in write mode

while(<FILE1>)
if($_=s/string/found/g)
push FILE2, $_...

I am able to change the contents however the when i read the file it has ^M in it..

my datafile is of the below format

name 'SAMPLE'

i would like to change this to

name 'SAMPLE2'

currently with my code it changes to

name 'SAMPLE2
'

which creates a new line and then does the replacement.

Do i need to use anyother mode to open the file to write..?


Solution

  • My guess is, that you are working with a linux file on some windows. Perl automatically converts \n into \r\n on dos-compatible machines after reading and before writing. To get rid of this behaviour, you can use binmode <FILE> on your filehandles, but it sets your filehandle into "raw binary mode". If you want to use some other layers (like :utf8 or :encoding(utf-8)) are not enabled, and you might want to set them yourself, if you are handling character data. You also could use the PerlIO::eol module from CPAN.

    Consider looking at these documentation pages:

    • PerlIO for a general understanding how the Perl-IO works.
    • open the pragma (not the function) to set layers for one program.
    • binmode the function you might want to consider.

    My suggestion, but I can't test it (no Windows around), would be to use the following:

    open my $outfile, '<:encoding(utf-8)', "filename" or die "error opening: $!";
    binmode $outfile, join '', grep {$_ ne ':crlf'} PerlIO::get_layers($outfile)
      or die "error setting output:\n $!"
    
    while(<$infile>){
      s/match/replacement/g;
      print $outfile $_;
    }