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

I have a text file that has new lines delimited by :::: and I need to replace that string with a \n character.

I have tried s/::::/\n/g; and s/::::/\r/g; And it works fine when displayed in a text file but I am importing that string into another program that displays the new lines as a tiny black box instead of a new line.

I copied text with a new line from the program I am importing into and it shows the line as CRLF hex 0d0a

Is there something I can do to replace with the CRLF it will accept?

I have also tried s/::::/hex(0d0a)/g; with no luck.

Replies are listed 'Best First'.
Re: string replace with CRLF
by imp (Priest) on Dec 19, 2006 at 19:33 UTC
Re: string replace with CRLF
by GrandFather (Saint) on Dec 19, 2006 at 19:44 UTC

    Show us a (runable) snippet of code demonstrating your problem. Your first attempt at a replace should be fine so long as you are not using binmode output - Perl generally "Does The Right Thing"™. In particular, on input the OS's line sep turns into a character represented by \n and on output the character represented by \n is turned into the appropriate line sep for the system.

    Note that, depending on the system, \n may not be a new line character. If you want to be sure you are getting a Windows CRLF pair then you need something like s/::::/\x{0D}\x{0A}/g;.

    See perliol for more discussion of the Perl IO layers.


    DWIM is Perl's answer to Gödel
Re: string replace with CRLF
by ikegami (Patriarch) on Dec 19, 2006 at 20:16 UTC

    You want to use "\n" if binmode isn't on.
    You want to use "\r\n" if binmode is on.

    use List::MoreUtils qw( apply ); for my $bin (0..1) { for my $eol ("\n", "\r", "\r\n") { my $name = $eol; $name =~ s/\r/cr/; $name =~ s/\n/lf/; $name .= '-bin' if $bin; { open(my $fh, '>', $name); binmode($fh) if $bin; print $fh map { "$_$eol" } qw( abc def ); } my $file = do { open(my $fh, '<', $name); binmode($fh); local $/; <$fh> }; my $data = join ' ', apply { s/\x0D/CR/ } apply { s/\x0A/LF/ } split //, $file; printf("%-9s %s\n", "$name:", $data); unlink($name); }}

    output

    lf: a b c CR LF d e f CR LF <- want cr: a b c CR d e f CR crlf: a b c CR CR LF d e f CR CR LF lf-bin: a b c LF d e f LF cr-bin: a b c CR d e f CR crlf-bin: a b c CR LF d e f CR LF <- want

    Update: Simplified the code a bit.
    Update: Oops, removed bug added in simplification. open(my $fh, '>', $file_name) defaults to :crlf, but open(my $fh, '>', \$file) does not!

      Note the following paragraph from perlport:

      Perl uses \n to represent the ``logical'' newline, where what is logical may depend on the platform in use. In MacPerl, \n always means \015. In DOSish perls, \n usually means \012, but when accessing a file in ``text'' mode, STDIO translates it to (or from) \015\012, depending on whether you're reading or writing. Unix does the same thing on ttys in canonical mode. \015\012 is commonly referred to as CRLF.

      so one of "\015\012" or "\x0d\x0a" is more reliable across platforms than "\r\n".


      DWIM is Perl's answer to Gödel

        MacPerl used to be different, but I was told that is no longer the case. MacPerl was the only exception, so now "\n" is always "\x0A" and "\r" in always "\x0D".

        But if you wanted to be sure, you'd use either
        "\n" without binmode or
        "\x0D\x0A" ("\015\012") with binmode.