在Perl中将内存大小(人类可读)转换为实际数量(字节)

在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::Format1K视为等于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字节