实际数(字节数)是否有实际的包在CPAN这种字符串转换:转换存储器大小(人类可读的)成在Perl
my $string = "54.4M"
my $string2 = "3.2G"
到实际数目字节:
54,400,000
3,200,000,000
反之亦然。
原则上我最终想做的是总结所有的内存大小。
实际数(字节数)是否有实际的包在CPAN这种字符串转换:转换存储器大小(人类可读的)成在Perl
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(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
}
绕通Number::Format的format_number
功能的数量,如果你想漂亮分号(例如, “5,124”,而不是 “5124”)
CPAN解决您的问题的第二部分:
例如:
use Number::Bytes::Human qw(format_bytes);
$size = format_bytes(54_400_000);
你可以提供一个可选的bs => 1000
参数转换的基础基本上更改为1000,而不是1024
听起来像你应该打包第一个案例数::字节::不人道:-) – justintime 2010-04-01 02:29:00
,从字符串到数字去,你需要的是一个散列映射单元给乘法器:
#!/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
你确定你会使用10的权力? – 2010-04-01 01:55:36
@Alex我不会。 IMNSHO,只有一个千字节的真正衡量标准,即1024字节。我不需要'KiB'废话;-)然而,OP使用10的幂,所以我就这样离开了它。 – 2010-04-01 01:58:37
一个小小的改进就是增加一个$ base变量,这样你可以设置一次,仍然可以使单位全部解决。 :) – 2010-04-01 02:16:45
这应该让你开始。你可以在你自己添加其他因素,如千字节(“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
这是我在“消除不必要的循环和分支”(http://www.effectiveperlprogramming.com/blog/23)中讨论的问题的反面,但您可以做出相同的改进。 :) – 2010-04-01 02:15:30
如果你已经在PerlMonks CB一分钟再到处挂着你会得到你的答案,基本上toolic的。 – MkV 2010-04-01 14:19:55