千字节到人类可读。寻找一班轮

发布于 2024-12-11 12:21:14 字数 766 浏览 0 评论 0原文

我经常在没有 du 的 -h 标志的 unix 机器上工作。

我正在寻找一种将 KB 转换为人类可读的单行代码。 Perl 似乎是一个不错的选择。
这就是我到目前为止所拥有的。

@a=split /\s+/;
$x=$_!=0?int(log()/log(1024)):0;
@b=('K','M','G');
printf("%.3s%s\t%s\n",$_/(1024)**$x,$b[$x],$a[1]);

像这样运行:

du -ks * | perl -lne '@a=split /\s+/;$x=$_!=0?int(log()/log(1024)):0;@b=('K','M','G');printf("%.3s%s\t%s\n",$_/(1024)**$x,$b[$x],$a[1]);'

它不能完美工作,因为我无法找到正确的 printf 格式。

使用 perl 以及 awk/sed 等的单行代码将是最有用的。

这就是 du -h 的样子。最多 1 位小数。最小值:0 位小数。带舍入。

8.0K
1.7M
4.0M
5.7M
88K

更新:

du -ks * | perl -lane '$F[0];$x=$_!=?int(log()/log(1024)):0;printf("%.3s%s\t%s\n",$_/1024**$x,qw<K M G>[$x],$F[1]);'

I often work on unix boxes that don't have the -h flag for du.

I am looking for a one-liner to convert KB to human readable. Perl seemed like a good choice.

This is what I have so far.

@a=split /\s+/;
$x=$_!=0?int(log()/log(1024)):0;
@b=('K','M','G');
printf("%.3s%s\t%s\n",$_/(1024)**$x,$b[$x],$a[1]);

Run like this:

du -ks * | perl -lne '@a=split /\s+/;$x=$_!=0?int(log()/log(1024)):0;@b=('K','M','G');printf("%.3s%s\t%s\n",$_/(1024)**$x,$b[$x],$a[1]);'

It doesn't work perfectly as I haven't been able to find the correct printf format.

one-liners using perl as well as awk/sed, etc. would be the most useful.

This is what du -h looks like. Max 1 decimal. Min: 0 decimals. With Rounding.

8.0K
1.7M
4.0M
5.7M
88K

Update:

du -ks * | perl -lane '$F[0];$x=$_!=?int(log()/log(1024)):0;printf("%.3s%s\t%s\n",$_/1024**$x,qw<K M G>[$x],$F[1]);'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凶凌 2024-12-18 12:21:14

这使用 CPAN 中的 Number::Bytes::Human

du -ks * |perl -MNumber::Bytes::Human=format_bytes -nle \
    '@F=split(/\s+/,$_,2); printf("%-10s%s\n", format_bytes($F[0]*1024), $F[1])'

编辑:不使用模块:

du -ks * |perl -nle \
   '@F=split(/\s+/,$_,2); $b=$F[0]*1024; for($i=0;$b>1024;$i++){$b/=1024} $u=qw{B K M G T}[$i]; printf("%10.".($b=~/\./?1:0)."f$u  %s\n", $b, $F[1])'

This uses Number::Bytes::Human from CPAN:

du -ks * |perl -MNumber::Bytes::Human=format_bytes -nle \
    '@F=split(/\s+/,$_,2); printf("%-10s%s\n", format_bytes($F[0]*1024), $F[1])'

EDIT: Without using modules:

du -ks * |perl -nle \
   '@F=split(/\s+/,$_,2); $b=$F[0]*1024; for($i=0;$b>1024;$i++){$b/=1024} $u=qw{B K M G T}[$i]; printf("%10.".($b=~/\./?1:0)."f$u  %s\n", $b, $F[1])'
凉风有信 2024-12-18 12:21:14
du -sk * | perl -ane '
  $i=0;
  while ($F[0]>1024) {$F[0]/=1024; $i++}; 
  printf("%d%s\t%s\n", $F[0], qw(K M G)[$i], $F[1])
'

如果您想要较大数字的分数:

du -sk * | perl -ane '
  $i=0;
  while ($F[0]>1024) {$F[0]/=1024; $i++;};
  $f = $i==0 ? "d" : ".2f"; 
  printf("%$f%s\t%s\n", $F[0], qw(K M G)[$i], $F[1])
'
du -sk * | perl -ane '
  $i=0;
  while ($F[0]>1024) {$F[0]/=1024; $i++}; 
  printf("%d%s\t%s\n", $F[0], qw(K M G)[$i], $F[1])
'

If you want fractions on the bigger numbers:

du -sk * | perl -ane '
  $i=0;
  while ($F[0]>1024) {$F[0]/=1024; $i++;};
  $f = $i==0 ? "d" : ".2f"; 
  printf("%$f%s\t%s\n", $F[0], qw(K M G)[$i], $F[1])
'
无戏配角 2024-12-18 12:21:14

您正确的 printf() 格式:

sub get_filesize_str
{
    my $file = shift;

    my $size = (stat($file))[7] || die "stat($file): $!\n";

    if ($size > 1099511627776) {   #   TiB: 1024 GiB
        return sprintf("%.2f TiB", $size / 1099511627776);
    } elsif ($size > 1073741824) { #   GiB: 1024 MiB
        return sprintf("%.2f GiB", $size / 1073741824);
    } elsif ($size > 1048576) {    #   MiB: 1024 KiB
        return sprintf("%.2f MiB", $size / 1048576);
    } elsif ($size > 1024) {       #   KiB: 1024 B
        return sprintf("%.2f KiB", $size / 1024);
    } else {                       #   bytes
        return sprintf("%.2f bytes", $size);
    }
}

这不是我的代码,它取自此处

your correct printf() format:

sub get_filesize_str
{
    my $file = shift;

    my $size = (stat($file))[7] || die "stat($file): $!\n";

    if ($size > 1099511627776) {   #   TiB: 1024 GiB
        return sprintf("%.2f TiB", $size / 1099511627776);
    } elsif ($size > 1073741824) { #   GiB: 1024 MiB
        return sprintf("%.2f GiB", $size / 1073741824);
    } elsif ($size > 1048576) {    #   MiB: 1024 KiB
        return sprintf("%.2f MiB", $size / 1048576);
    } elsif ($size > 1024) {       #   KiB: 1024 B
        return sprintf("%.2f KiB", $size / 1024);
    } else {                       #   bytes
        return sprintf("%.2f bytes", $size);
    }
}

that's not my code, it was taken from here

帅的被狗咬 2024-12-18 12:21:14

如果您想要进行的唯一修改(不清楚您想要什么)是让数字在 3 个字符的字段中右对齐,只需从 printf 格式中删除句点即可。另外,我建议不要显式调用 split 并将整个 $_ 视为数字,而是建议向 Perl 传递 -a 开关,该开关自动将空格上的 $_ 拆分到数组 @F 中,然后将代码中对 $_ 的引用替换为 $F [0]

因此,您的代码可以重写(使用更多 Perlism 并添加一些空格以提高可读性):

du -ks * | perl -lane '$x = $F[0] != 0 && int(log($F[0])/log(1024)); printf("%3d%s\t%s\n", $F[0]/1024**$x, qw<K M G>[$x], $F[1]);'

If the only modification you want to make (It's not clear what you want) is to have the number be right-aligned in a field of 3 characters, simply drop the period from the printf format. Also, rather than explicitly calling split and treating the whole of $_ as a number, I would recommend passing Perl the -a switch, which automatically splits $_ on whitespace into the array @F, and then replace the references to $_ in your code with $F[0].

Your code could thus be rewritten (using a couple more Perlisms and adding some spaces for readability) as:

du -ks * | perl -lane '$x = $F[0] != 0 && int(log($F[0])/log(1024)); printf("%3d%s\t%s\n", $F[0]/1024**$x, qw<K M G>[$x], $F[1]);'
溇涏 2024-12-18 12:21:14

这是改编自 stackoverflow 上的一些答案的 AWK 函数:

function human_readable(sum) {

hum[1024**3]="GiB";hum[1024**2]="MiB";hum[1024]="KiB"; 
    for (x=1024**3; x>=1024; x/=1024){ 
        if (sum>=x) { v = sprintf( "%.2f %s",sum/x,hum[x]); return v }
    }
}

Here is AWK function adapted from some answer on stackoverflow:

function human_readable(sum) {

hum[1024**3]="GiB";hum[1024**2]="MiB";hum[1024]="KiB"; 
    for (x=1024**3; x>=1024; x/=1024){ 
        if (sum>=x) { v = sprintf( "%.2f %s",sum/x,hum[x]); return v }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文