evgen-i has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

my Perl script runs on Windows via Strawberry Perl and writes output to a file. All lines it prints end with "\n". When I open the output file, however, I see that the the Windows carriage returns "\r\n" were written instead. Is there a way I can force the script to write Unix newlines "\n" only?

Thank you!
  • Comment on How to print Unix newlines in Strawberry Perl on Windows

Replies are listed 'Best First'.
Re: How to print Unix newlines in Strawberry Perl on Windows
by BrowserUk (Patriarch) on Feb 20, 2013 at 12:42 UTC

    In order to write Unix line ending, simply binmode the file after opening and before use and do the 'normal' thing of using "\n" for your line endings.

    There are other ways involving explicitly 'popping' the :crlf IOLayer when opening the file, but it isn't documented properly and I cannot remember how to do it.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: How to print Unix newlines in Strawberry Perl on Windows
by karlgoethebier (Abbot) on Feb 20, 2013 at 14:28 UTC
    "...force the script to write Unix newlines "\n" only?"

    Perhaps like this:

    #!c:/perl/bin/perl.exe use Data::Dumper; use strict; use warnings; my $string = qq(foo\nbar\n); open my $fh, '>', "dos.txt"; my @layers = PerlIO::get_layers($fh, output => 1); # edit print Dumper(\@layers); print $fh $string; close $fh; open $fh, '>:pop', "unix.txt"; @layers = PerlIO::get_layers($fh, output => 1); print Dumper(\@layers); print $fh $string; close $fh; __END__ $VAR1 = [ 'unix', 'crlf' ]; $VAR1 = 'unix'; $ hexdump.exe -c dos.txt 0000000 f o o \r \n b a r \r \n 000000a $ hexdump.exe -c unix.txt 0000000 f o o \n b a r \n 0000008

    Update: See also PerlIO and Get record separator of a file. And thanks to davido.

    Update2: Funky question: How can i do the same thing using IO::All? I've been playing around with it but i don't have a real plan for the moment. Perhaps i don't understand the manual. Or i miss something, as you like.

    Update3: (awkward)

    use IO::All; io("io.txt")->binmode(':unix')->print($string); __END__ $ hexdump.exe -c io.txt 0000000 f o o \n b a r \n 0000008

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

Re: How to print Unix newlines in Strawberry Perl on Windows
by vinoth.ree (Monsignor) on Feb 20, 2013 at 12:35 UTC
Re: How to print Unix newlines in Strawberry Perl on Windows
by roboticus (Chancellor) on Feb 20, 2013 at 11:56 UTC

    evgen-l:

    I defer to the correct answers below.

    You can set the output record delimiter ($/ see perlvar for details) like so:

    print "default line ending:\n"; { local $/="\n"; print "Unix line ending:\n"; } { local $/="\r\n"; print "Win/DOS line ending:\n"; } { local $/="\r"; print "Antique MAC line ending:\n"; }

    Note: Untested, etc... Standard disclaimers apply.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      In addition to Athanasius' caveats, realise that when you write "\n" to a text file, the OS will add the "\r" for you.

      Thus your advice to use local $/="\r\n"; will result in "\r\r\n" being written if the file is in text mode.

      In order to avoid that addition, you must binmode the file. Or remove the :crlf layer from the perlIO stack.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      $/ is the input record separator. The output record separator is $\. See The parable of the falling droplet.

      Also, the default value of $\ is undef (meaning that nothing will be automatically appended to each printed line). If you set $\ as shown, you should omit the trailing "\n":

      { local $\ = "\r\n"; print "Win/DOS line ending"; }

      — otherwise, you will get "\n\r\n" printed at the end of the string.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,