Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl printf to use commas as thousands-separator

Tags:

perl

Using awk, I can print a number with commas as thousands separators.
(with a export LC_ALL=en_US.UTF-8 beforehand).

awk 'BEGIN{printf("%\047d\n", 24500)}'

24,500

I expected the same format to work with Perl, but it does not:

perl -e 'printf("%\047d\n", 24500)'

%'d

The Perl Cookbook offers this solution:

sub commify {
    my $text = reverse $_[0];
    $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
    return scalar reverse $text;
}

However I am assuming that since the printf option works in awk, it should also work in Perl.

like image 743
Chris Koknat Avatar asked Oct 30 '15 18:10

Chris Koknat


3 Answers

Here's an elegant Perl solution I've been using for over 20 years :)

1 while $text =~ s/(.*\d)(\d\d\d)/$1\.$2/g;

And if you then want two decimal places:

$text = sprintf("%0.2f", $text);
like image 85
Y.K. Avatar answered Oct 03 '22 13:10

Y.K.


The apostrophe format modifier is a non-standard POSIX extension. The documentation for Perl's printf has this to say about such extensions

Perl does its own "sprintf" formatting: it emulates the C function sprintf(3), but doesn't use it except for floating-point numbers, and even then only standard modifiers are allowed. Non-standard extensions in your local sprintf(3) are therefore unavailable from Perl.

The Number::Format module will do this for you, and it takes its default settings from the locale, so is as portable as it can be

use strict;
use warnings 'all';
use v5.10.1;

use Number::Format 'format_number';

say format_number(24500);

output

24,500
like image 10
Borodin Avatar answered Oct 17 '22 20:10

Borodin


A more perl-ish solution:

$a = 12345678;                 # no comment
$b = reverse $a;               # $b = '87654321';
@c = unpack("(A3)*", $b);      # $c = ('876', '543', '21');
$d = join ',', @c;             # $d = '876,543,21';
$e = reverse $d;               # $e = '12,345,678';
print $e;

outputs 12,345,678.

like image 10
syck Avatar answered Oct 17 '22 19:10

syck