lorenak has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I checked the FAQ for help, and the code section, but I'm still at a loss. I'm trying to write a little dos2unix module that runs on Windows 2000. I found and borrowed the version here at http://www.perlmonks.org/index.pl?node_id=215707. I only need to convert CRLF to LF, DOS to UNIX. However, no matter how I try the conversion, it seems that I can't get rid of that pesky CR. Here's what I have:
sub dos2unix { # Takes array containing file-paths as argument my (@files2Convert) = @_; foreach my $file (@files2Convert) { if (-e $file) { print "Converting $file...\n"; # load file contents into memory for conversion open(FILE, "$file") or die "Can't open $file: $!"; my @lines = <FILE>; close(FILE) or die "Can't close $file: $!"; # here's where the actual conversion takes place foreach my $i ( 0..$#lines ) { $lines[$i] =~ s/\015\012/\012/g; } # make backup copy of file in case this module dies halfway th +rough # the write to the new file. (We only have this file info in m +emory at that point.) rename("$file","${file}.bak") or die "Couldn't make backup copy of + $file: $!"; # write new data open(FILE,">$file") or die "Can't open $file: $!"; print FILE @lines; close(FILE) or die "Can't close $file: $!"; # remove backup if all is successful unlink "${file}.bak" or warn "Couldn't remove backup of $file: $!" +; } } }
This code doesn't change the file at all. So, I tried various replacements for the regex line:
$lines[$i] =~ s/\015\012/\012/g; $lines[$i] =~ s/\n/\012/g; $lines[$i] =~ s/\x0D\x0A/\012/g; $lines[$i] =~ s/\015\012/\x0A/g; $lines[$i] =~ s/\n/\x0A/g; $lines[$i] =~ s/\x0D\x0A/\x0A/g;
All with the same result- no change, still CRLF. I even read up in the Camel book about the Socket module, and tried the following:
use Socket qw(:DEFAULT :crlf); local ($/) = LF; $lines[$i] =~ s/$CRLF/$LF/g;
But the file remained CRLF.I did some experimentation, and it looks like \012 is set to "CRLF" on my system somehow because the following removes the entire line delimiter:
$lines[$i] =~ s/\012//g;
I copied the code over to UNIX with a few CRLF files, and it worked fine. I'm sure I'm missing something simple, has anyone else encountered this before?

Replies are listed 'Best First'.
Re: Perl Dos2Unix on Windoze?
by PodMaster (Abbot) on Jun 25, 2003 at 20:27 UTC
    `perldoc -f binmode'

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      Ah, that's it! I knew it was something small that I was missing. Thanks.

      I can't seem to make that work in this oneliner:

      perl -pi~ -e "binmode ARGV; s/\cM//"
        That's cause <> is magic (see Dangerous diamonds!), and ARGV isn't open when you binmode.

        `perldoc open'. Try something like perl -Mopen=IN,:raw,OUT,:raw -pi~ -e "s/\cM//"

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Perl Dos2Unix on Windoze?
by jsprat (Curate) on Jun 25, 2003 at 21:28 UTC
    Windows does the translation when writing to disk. tye explains it all very well here: Re^4: Line Feeds (rumor control) An informative write-up, and very undernourished - a ++ for that node is well deserved