在CPAN中是否有实际的包来转换这样的string:
my $string = "54.4M" my $string2 = "3.2G"
以字节为单位的实际数字:
54,400,000 3,200,000,000
反之亦然。
原则上我最终想做的是总结所有的内存大小。
为了得到你要求的确切输出,使用Number :: FormatEng和Number :: Format :
use strict; use warnings; use Number::FormatEng qw(:all); use Number::Format qw(:subs); my $string = "54.4M" ; my $string2 = "3.2G" ; print format_number(unformat_pref($string)) , "\n"; print format_number(unformat_pref($string2)) , "\n"; __END__ 54,400,000 3,200,000,000
顺便说一下,如果您要执行结果的计算,则只需要unformat_pref
。
由于Number :: FormatEng用于工程符号转换(不适用于字节),因此其前缀区分大小写。 如果你想使用千字节,你必须使用小写字母k
。
Number :: Format将这些字符串转换为实际的字节(几乎是)。
use Number::Format qw(:subs); my $string = "54.4M" ; my $string2 = "3.2G" ; print round(unformat_number($string) , 0), "\n"; print round(unformat_number($string2), 0), "\n"; __END__ 57042534 3435973837
我说“有点,差不多”的原因是Number::Format
将1K
视为等于1024个字节,而不是1000个字节。 这可能是为什么它会给出一个奇怪的结果(小数字节),除非它是四舍五入的。
对于你的第一个问题,我没有找到一个CPAN包,但是这个代码片段可能会:
sub convert_human_size { my $size = shift; my @suffixes = ('', qw(kmg)); for my $index (0..$#suffixes) { my $suffix = $suffixes[$index]; if ( $size =~ /^([\d.]+)$suffix\z/i ) { return int($1 * (1024 ** $index)); } } # No match die "Didn't understand human-readable file size '$size'"; # or croak }
如果你想要漂亮的分号(例如“5,124”而不是“5124”),则通过Number :: Format的format_number
函数来包装数字
CPAN解决了问题的第二部分:
数::字节::人
例如:
use Number::Bytes::Human qw(format_bytes); $size = format_bytes(54_400_000);
您可以提供一个可选的bs => 1000
参数,将转换基数改为1000而不是1024。
这应该让你开始。 您可以添加其他因素,例如您自己的千字节(“K”),以及输出的格式(例如,逗号分隔符):
#!/usr/bin/perl -w use strict; use POSIX qw(floor); my $string = "54.4M"; if ( $string =~ m/(\d+)?.(\d+)([M|G])/ ) { my $mantissa = "$1.$2"; if ( $3 eq "M" ) { $mantissa *= (2 ** 20); } elsif ( $3 eq "G" ) { $mantissa *= (2 ** 30); } print "$string = ".floor($mantissa)." bytes\n"; }
输出:
54.4M = 57042534 bytes
基本上,要从字符串到数字,所有你需要的是一个哈希映射单位乘法器:
#!/usr/bin/perl use strict; use warnings; my $base = 1000; my %units = ( K => $base, M => $base ** 2, G => $base ** 3, # etc ); my @strings = qw( 54.4M 3.2G 1K 0.1M .); my $pattern = join('|', sort keys %units); my $total; for my $string ( @strings ) { while ( $string =~ /(([0-9]*(?:\.[0-9]+)?)($pattern))/g ) { my $number = $2 * $units{$3}; $total += $number; printf "%12s = %12.0f\n", $1, $number;; } } printf "Total %.0f bytes\n", $total;
输出:
54.4M = 54400000 3.2G = 3200000000 1K = 1000 0.1M = 100000 总共3254501000字节