in reply to Printing large numbers with commas to show thousands groups.
Thanks for the feedback! I forgot to mention String::Sprintf in my post, thanks for pointing it out as another possibility. I was unaware of FFI::Platypus, which looks really interesting for a lot of possible things. Too bad it isn't included in the core, but I guess portability to windows, etc, is a priority these days. Thanks for making me aware of it.
After a bit more rumination, I though of another approach. One could post-process output to add commas, instead of modifying the code. This can be applied to the output of any program, or to data or log files. It might seem that deciding which numbers to commify would be an impossible task. It is, of course. But the following simple script seems to work surprisingly well.
-Jeff
#! /usr/bin/perl -w # commify.pl: commify *all* of the numbers in a file (or stdin). # Well, almost all. Add commas to strings of at least 5 digits, that # don't follow a decimal pt, comma, or word char, and don't start with # a zero. while (<>) { s/(?<! [.,\w]) ([1-9] \d{4,})/commify_digits($1)/egx; print; } sub commify_digits { local($_)= shift; s/(\d)(?=(\d{3})+$)/$1,/g; return $_; } =pod A few notes: Not commifying 4-digit numbers reduces the occurrence of unwanted commas. For example, we don't want "Dec 31, 2,019". A comma doesn't really add to the readability of a small number anyway. A string of digits beginning with a zero might be an octal number. Even if it isn't, 004,200,000 looks wrong, and 00,245 is confusing. If there is a word char before the digits, it might be part of a name of some sort: var1234567, or file_424242.txt. Or, it might be hex: 0x123456. We don't examine the character that follows the digits, since it may start a suffix: 1459798sec becomes 1,459,798sec. This is far from perfect, but seems to be useful. You can use it for data or log files which contain large numbers. You can also try to commify the output of ls, du, df, etc. For example, here are three views of a large iso image: $ ls -l devuan_dvd.iso -rw-rw-r-- 1 jeff jeff 4658798592 Oct 5 2018 devuan_dvd.iso $ ls -lh devuan_dvd.iso -rw-rw-r-- 1 jeff jeff 4.4G Oct 5 2018 devuan_dvd.iso $ ls -l devuan_dvd.iso | commify -rw-rw-r-- 1 jeff jeff 4,658,798,592 Oct 5 2018 devuan_dvd.iso The longer output of 'ls -l|commify' won't be as nice, since the columns become misaligned. It's not too bad, though, considering that it is produced by just 7 lines of code, The first s/// uses a negative-lookbehind to search for strings of digits, and then passes them to commify_digits. You can modify '[.,\w]' to adjust which digit strings are commified, or change '\d{4,}' to set the minimum length. The s/// in commify_digits is simple, since it gets an entire string of digits. It just adds a comma after each digit that is followed by a multiple of three (to the end of the string). Jeff Norden, Dec 2019. This code is in the public domain. =cut
|
|---|