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

I need to replace all the CR(\r) LF(\n) characters (0d 0a in hex) with only LF in a text file ON WINDOWS. In other words, I want to convert a Windows text file to a Unix text file format using Perl...BUT from a Window system, NOT a UNIX system. Simply trying to replace the CR in a substitution string doesn't work. Windows seems to be working against me in that it always puts the CR back with the LF when I do a replace and write the file. A substitution like s/\s+$/\n/; does work, but removes too much because it also removes the LF characters, which I need. I found a few related solutions poking around the Web, but unfortunately, they were intended for execution on UNIX (for example, perl -p -e 's/\r$//' < winfile.txt > unixfile.txt ). Does anyone know of a Windows code solution, or will I need to do something more drastic like edit the binary? Thanks in advance for any assistance. -- New Group member

Replies are listed 'Best First'.
Re: Remove CR from file on Windows
by ikegami (Patriarch) on Feb 09, 2007 at 21:33 UTC

    Unless you use binmode on your input file, CRLF gets converted to LF on read.
    Unless you use binmode on your output file, LF gets converted to CRLF on write.

    To convert a Windows file to a unix file (on any machine):

    binmode($fh_in); binmode($fh_out); while (<$fh_in>) { s/\x0D\x0A/\x0A/g; print $fh_out $_; }
Re: Remove CR from file on Windows
by dsheroh (Monsignor) on Feb 09, 2007 at 20:58 UTC
    You can use binmode (FILE) to put FILE into binary mode after opening it, which should disable line end translation. You'll probably need to do this for both your input and your output files.
Re: Remove CR from file on Windows
by davidrw (Prior) on Feb 10, 2007 at 04:53 UTC
    this should work just fine in DOS (note you have to use double quotes for the -e param):
    perl -pe "s/\r(?=\n)//" winfile.txt > unixfile.txt
    see perlre for the postive look-ahead

    or to do it in-place (see perlrun):
    perl -i.bak -pe "s/\r(?=\n)//" winfile.txt > unixfile.txt
    demo batch file:
    perl -e "print \"foo\r\nbar\r\nstuff\";" > f.txt perl -pe "s/(\s)/'['.ord($1).']'/esg" f.txt REM output: foo[13][10]bar[13][10]stuff perl -i.bak -pe "s/\r(?=\n)//" f.txt perl -pe "s/(\s)/'['.ord($1).']'/esg" f.txt REM output: foo[10]bar[10]stuff
      None of those work in Windows. (I presume that's what you meant by DOS.)
      >echo Hello > winfile.txt >echo World >> winfile.txt >perl -pe "s/\r(?=\n)//" winfile.txt > unixfile.txt >debug unixfile.txt -rcx CX 0010 : -d100 l10 0AF7:0100 48 65 6C 6C 6F 20 0D 0A-57 6F 72 6C 64 20 0D 0A Hello ..W +orld .. -q

      Well, they might work with a simulated unix environment in Windows (like cygwin), but that's an entirely different world.

      The earlier posts in this thread not only provided the solution, they explained this problem and the workaround.

      If it's one-liners you wanted,

      • Works anywhere:
        perl -pe "BEGIN { binmode STDIN; binmode STDOUT } s/\x0D(?=\x0A)//" winfile.txt > unixfile.txt
      • Works on Windows:
        perl -pe "BEGIN { binmode STDIN }" winfile.txt > unixfile.txt
      • Works on unix:
        perl -ple 'BEGIN { $/="\r\n" }' winfile.txt > unixfile.txt
        I tested (in a DOS window on WindowsXP, striaght -- no cygwin) all of what i posted .. I don't understand -- why doesn't it work??
        C:\foo>type foo.bat @echo OFF echo "making test file" perl -e "print \"foo\r\nbar\r\nstuff\";" > f.txt echo "showing test file" perl -pe "s/(\s)/'['.ord($1).']'/esg" f.txt echo "altering file" perl -i.bak -pe "s/\r(?=\n)//" f.txt echo "showing result" perl -pe "s/(\s)/'['.ord($1).']'/esg" f.txt C:\foo>foo.bat "making test file" "showing test file" foo[13][10]bar[13][10]stuff "altering file" "showing result" foo[10]bar[10]stuff C:\foo>
Re: Remove CR from file on Windows
by poltr1 (Novice) on Nov 01, 2011 at 14:40 UTC

    Unfortunately, Windows has been known to not play well with other OSes, and thus, there are no "dos2unix" or "unix2dos" commands built-in. :-( I haven't recently checked if there are any open-source add-ins or commands to do this.

    Some text editor programs allow you to change the file attributes. I happen to use the open-source Crimson Editor (now called Emerald Editor). In Crimson Editor, the menu comand "Document | File Format" will give you a choice between DOS format (CR/LF), Unix format (LF only), or Mac format (CR only).

    And then there's Cygwin. :-)