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

时间:2010-04-01 01:35:58

标签: linux perl unix

CPAN中是否有实际的包来转换这样的字符串:

my $string = "54.4M"
my $string2 = "3.2G"

到实际的字节数:

54,400,000
3,200,000,000

反之亦然。

原则上我最后要做的就是总结所有内存大小。

4 个答案:

答案 0 :(得分:5)

要获取您要求的完全输出,请使用Number::FormatEngNumber::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字节。这可能就是为什么它会给出一个奇怪的结果(带小数字节),除非它是舍入的。

答案 1 :(得分:4)

对于您的第一个问题,我没有找到CPAN软件包,但此代码段可能会执行此操作:

sub convert_human_size {
    my $size = shift;
    my @suffixes = ('', qw(k m g));
    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::Formatformat_number功能包裹号码

CPAN解决了问题的第二部分:

Number::Bytes::Human

例如:

  use Number::Bytes::Human qw(format_bytes);
  $size = format_bytes(54_400_000);

您可以提供一个可选的bs => 1000参数,将转换基数更改为1000而不是1024.

答案 2 :(得分:1)

基本上,从字符串到数字,您只需要一个哈希映射单元到乘数:

#!/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
Total 3254501000 bytes

答案 3 :(得分:1)

这应该让你开始。您可以自己添加其他因素,如千字节(“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