Of course, there are plenty of potential pitfalls to this simple approach
Here's another approach to that without invocation of a sprintf binary, so no shell danger. Simply interpolate the "babycart operator" @{[]} into the format for any %'d conversion, call sprintf, then eval the result as a string. So something like
cprintf "There are at least %'d ways to do it!\n", 42e6;
will effectively result in
printf "There are at least @{[commify('%d')]} ways to do it!\n", 42e6;
with the difference that, unlike printf, the interpolation is done before the expansion of @{[]}
(printf evaluates the expansion first, i.e. it calls commify with a literal '%d', and then interpolates the value. Bug?)
but without the @{[]} evaluation being done at the time the format is assembled.
All other perl sprintf conversions and flags can be used within the format.
This does the trick:
sub commify { local $_ = shift; my $spc = ''; s/^(\s+)// and $spc = $1; # trim and save leading sp +ace my $adj = 0; $adj++ while s/^([-+]?\d+)(\d{3})/$1,$2/; $spc =~ s/.{$adj}//; # adjust space for commas added s/\s{0,$adj}$// if /\s$/; # adjust right padding return $spc . $_; } sub cprintf { (my $format = shift) =~ s{ \%(['+0-9.-]+)?([df]) # capture all valid %d and %f flags +and modifiers }{ my $p = $1; my $c = $2; $p =~ s/'// ? "\@{[commify('%$p$c')]}" : "%$p$c" }gex; my $str = sprintf $format, @_; print eval "\"$str\""; } cprintf "%+'012d\n", 1e6; cprintf "<%-'12.6d>\n", 1e6; cprintf "<%-+12.6'd>\n", 1e6; cprintf "<%+12.6'd>\n", -1e6; cprintf "<%+12.6d>\n", -1e6; cprintf "<%+12.2'f>\n", 1234.5; cprintf "There are at least %'d ways to do it!\n", 42e6; __END__ +00,001,000,000 <1,000,000 > <+1,000,000 > < +1,000,000> < -1,000,000> < -1000000> < +1,234.50> There are at least 42,000,000 ways to do it!
Of course, neither your nor my approach works for the printf FILEHANDLE FORMAT, LIST form of printf.
update: fixed format substitution
In reply to Re: Printing large numbers with commas to show thousands groups.
by shmem
in thread Printing large numbers with commas to show thousands groups.
by jnorden
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |