shell 使用Bash将KB转换为MB

sq1bmfud  于 2023-03-24  发布在  Shell
关注(0)|答案(8)|浏览(284)

我使用一个命令来获取远程文件夹的大小,运行后返回

120928312 http://blah.com

这个数字的大小是bytes。我想做的是让它以MB输出,并删除http部分。我猜greping到一个文件,但不知道如何去做。

vpfxa7rd

vpfxa7rd1#

你可以用shell内置的

some_command | while read KB dummy;do echo $((KB/1024))MB;done

下面是一个更有用的版本:

#!/bin/sh
human_print(){
while read B dummy; do
  [ $B -lt 1024 ] && echo ${B} bytes && break
  KB=$(((B+512)/1024))
  [ $KB -lt 1024 ] && echo ${KB} kilobytes && break
  MB=$(((KB+512)/1024))
  [ $MB -lt 1024 ] && echo ${MB} megabytes && break
  GB=$(((MB+512)/1024))
  [ $GB -lt 1024 ] && echo ${GB} gigabytes && break
  echo $(((GB+512)/1024)) terabytes
done
}

echo 120928312 http://blah.com | human_print
7qhs6swi

7qhs6swi2#

这条线怎么样:

$ echo "120928312 http://blah.com" | awk '{$1/=1024;printf "%.2fMB\n",$1}'
118094.05MB
5jvtdoz2

5jvtdoz23#

尝试使用bash内置函数(显示一个整数,就像KB版本一样)

var="120928312 http://blah.com"
echo "$(( ${var%% *} / 1024)) MB"
uubf1zoe

uubf1zoe4#

function bytes_for_humans {
    local -i bytes=$1;
    if [[ $bytes -lt 1024 ]]; then
        echo "${bytes}B"
    elif [[ $bytes -lt 1048576 ]]; then
        echo "$(( (bytes + 1023)/1024 ))KiB"
    else
        echo "$(( (bytes + 1048575)/1048576 ))MiB"
    fi
}

$ bytes_for_humans 1
1 Bytes
$ bytes_for_humans 1024
1KiB
$ bytes_for_humans 16777216
16MiB
xj3cbfub

xj3cbfub5#

使用bcprintf

bcprintf可用于显示具有可配置小数位数的输出,也可对数字进行分组:

$ KB=1234567890
$ echo "$KB / 1000" | bc -l | xargs -i printf "%'.1f MB" {}
1,234,567.9 MB

使用numfmt

使用numfmt自动缩放输出单位:

$ numfmt --from=iec --to=si 123456789K
127G
$ numfmt --from=si --to=iec 123456789K
115G

要使用numfmt输出到固定单元,例如M

$ numfmt --from=iec --to-unit=1M --grouping 123456789K
126,420

$ numfmt --from=si --to-unit=1Mi --grouping 123456789K
117,738

请参阅其手册页并确保正确使用。

nr9pn0ug

nr9pn0ug6#

尝试使用awk

awk '{MB=$1/1024; print $MB}'

$1-第一列的值,本例中为大小(KB)

fzwojiic

fzwojiic7#

Github:index0-b-to-mb.sh

index0-b-to-mb.sh

#! /bin/bash --posix

    # requirements: vim-common
    # sudo dnf -y install vim-common

    function b_to_mb {
      # get BASE conversion type
      if [ "$3" = "BASE10" ]; then
        # set for BASE10
        BASE_DIV=1000000
      else
          if [ "$3" = "MIXED" ]; then
          # set for MIXED
          BASE_DIV=1024000
          else
          # set default for BASE2
          BASE_DIV=1048576
          fi
      fi
      # create array from string
      # use bc with 6 digit precision to calculate megabytes from bytes
      ARRAY=($1) && printf "scale=6; ${ARRAY[0]}/$BASE_DIV\n" | bc -l
    }
    # execute b_to_mb
    b_to_mb $1 $2

https://en.wikipedia.org/wiki/Megabyte#Definitions
./index0-b-to-mb.sh '120928312 http://blah.com' MIXED

118.094054

./index0-b-to-mb.sh '120928312 http://blah.com' BASE10

120.928312

./index0-b-to-mb.sh '120928312 http://blah.com' BASE2

115.326225

./index0-b-to-mb.sh '120928312 http://blah.com'

115.326225

./index0-b-to-mb.sh "$(your_command)"

115.326225
wtlkbnrh

wtlkbnrh8#

下面是我编写的一个小例程,它只依赖于bash,并将任何大于1000的十进制字节值格式化为以K为单位的估计值(1024)、M(1024K),G(1024 M),T,Peta,Exa。它四舍五入到最近的十分位。最初的目的是将输出限制为固定的位数6,模拟pv命令的输出。仅用于估计目的,例如KB/秒传输速率。

gmk_fmt () { # bytes
  # Apply a suffix to any byte value greater than 999.  Returns a string w/len at most 6 
  # (f5.1 + modifier) with the appropriate modifier, K, M, G, T, P, E.
  # Example: gb_fmt 370220929180 returns 344.7G
  b=$1
  d=0
  s="EPTGMK "
  while [ $b -ge 1000 ] ; do
    d=$(((($((($b & 1023)))*100/1024)+5)/10))   # remainder mod 1024, rnd to nearest tenth
    b=$(( ($b ) >> 10 ))                        # divide by 1024
    s=${s:: -1}                                 # advance the prefix
  done
  [ $d -ge 10 ] && { let b++ ; d=0; }           # if rem is ".10," then bump the top unit
  [ $d -gt 0 ] && suf=".$d"                     # apply decimal only if not a zero
  echo ${b}${suf}${s: -1}
}

这里有一些测试代码来驱动它。正如所写的那样,它将生成随机值和转换。将“false”更改为“true”进行增量测试以验证舍入:

let i=800
while [ $i -lt 1200 ] ; do
  if false ; then
    printf "%8s %s\n" $(gmk_fmt $i) $(bc<<<"scale=2; $i/1024")
  else
    n=$(($RANDOM * ( 1024 ** ($RANDOM & 3))))
    printf "%8s %s\n" $(gmk_fmt $n) $n
  fi
  let i++
done

相关问题