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

I'm looking for a method to convert newline-type characters to their octal forms. I've figured out how to get the hex representation:

perl -E 'say unpack "H*", "\r\n";'

...but I'd like to get this as "015012" as opposed to "0d0a".

I've been searching on and off today, testing with sprintf, oct and a myriad of other things, but I'm not familiar with this type of transormation (the above unpack was something unrelated I found online... I've never used or have needed to use pack before).

I'd like to point out that I'm not trying to ask "what is a better regex" or "should I use this or this" (so things like tye's Re: \r\n vs \012\015 (tye) aren't really relevant), and this isn't an XY Problem, I just am curious as to how it's done, regardless of need or use case.

-stevieb

Replies are listed 'Best First'.
Re: Transforming "\r\n" to '\012\015'
by AnomalousMonk (Archbishop) on Sep 20, 2015 at 22:11 UTC

    Maybe not the best way:

    c:\@Work\Perl>perl -wMstrict -le "print join '', map sprintf('%03o', $_), unpack 'C*', qq{\r\n}; " 015012
    See sprintf for  'o' template | format specifier.

    Update: Or maybe:

    c:\@Work\Perl>perl -wMstrict -le "my $x = qq{\r\n}; $x =~ s{(.)}{ sprintf '%03o', ord $1; }xmsge; print qq{'$x'}; " '015012'


    Give a man a fish:  <%-{-{-{-<

Re: Transforming "\r\n" to '\012\015'
by LanX (Saint) on Sep 20, 2015 at 22:13 UTC
    DB<106> sprintf '%03o%03o', ord("\r"),ord("\n") => "015012"

    if you need to convert a whole string, consider

    DB<104> map { sprintf '%03o', ord($_) } split //, "a \r\n" => (141, "040", "015", "012")

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    update

    improved null padding, that is %03o instead of 0%o in sprintf.

    the latter would produce:

    DB<109> sprintf '0%o', ord("a") => "0141"
Re: Transforming "\r\n" to '\012\015'
by RichardK (Parson) on Sep 20, 2015 at 22:14 UTC

    I'm not sure where you're going with this, but printf (see sprintf for full details) will output octal, if that's any help?

    perl -E 'printf("%#o\n",ord($_)) for split("","\r\n");' 015 012
Re: Transforming "\r\n" to '\012\015' ( octal escape encode pack implode )
by Anonymous Monk on Sep 20, 2015 at 22:13 UTC
Re: Transforming "\r\n" to '\012\015'
by Laurent_R (Canon) on Sep 21, 2015 at 16:45 UTC
    Hum, I have duly read your comments in the last paragraph, but still don't understand why you want to do this.

    Octal, decimal or hexadecimal are just representations of numbers. Under the hood, it is all binary, you usually don't have to worry.

    Granted, there are some protocols and commands that require being passed an octal representation, such as the chmod command because of (retrospectively slightly unfortunate, but probably justified at the time) decisions made by the Unix designers some 40 year ago.

    But as for changing "\r\n" to their octal representations, I can't see any real use case nowadays.

Re: Transforming "\r\n" to '\012\015'
by Anonymous Monk on Sep 21, 2015 at 16:40 UTC

    Adding to the ?above —

    A generic solution must escape the escape character also, otherwise the transformation isn't reversible.

    { my %T = ("\n" => "\\n", "\r" => "\\r", "\\" => "\\\\"); sub escape { s/[\r\n\\]/$T{$&}/g for @_ } }