du, ls1과 같이 바이트 수를 인간 KiB MiB 등으로 변환하는 표준 도구입니다.

du, ls1과 같이 바이트 수를 인간 KiB MiB 등으로 변환하는 표준 도구입니다.

당신은 가지고 있습니까?표준 도구숫자 값을 1.00에서 1023.99? 사이로 유지하면서 정수 바이트 수를 사람이 읽을 수 있는 가장 큰 단위 크기 수로 변환합니다.

나만의 bash/awk 스크립트가 있지만기준많은/대부분의 배포판에서 발견되는 도구... 보다 일반적으로 사용 가능한 도구이며 이상적으로는 간단한 명령줄 인수를 갖고/거나 파이프 입력을 받아들일 수 있습니다.

다음은 제가 찾고 있는 출력 유형의 몇 가지 예입니다.

    1    Byt  
  173.00 KiB  
   46.57 MiB  
    1.84 GiB  
   29.23 GiB  
  265.72 GiB  
    1.63 TiB  

여기있어바이트 인간스크립트(위 출력의 경우)

awk -v pfix="$1" -v sfix="$2" 'BEGIN { 
      split( "Byt KiB MiB GiB TiB PiB", unit )
      uix = uct = length( unit )
      for( i=1; i<=uct; i++ ) val[i] = (2**(10*(i-1)))-1
   }{ if( int($1) == 0 ) uix = 1; else while( $1 < val[uix]+1 ) uix--
      num = $1 / (val[uix]+1)
      if( uix==1 ) n = "%5d   "; else n = "%8.2f"
      printf( "%s"n" %s%s\n", pfix, num, unit[uix], sfix ) 
   }'

고쳐 쓰다  수정된 버전입니다자일스의그의 답변에 대한 댓글에서 언급했듯이 스크립트 .. (내가 좋아하는 모양에 맞게 수정됨).

awk 'function human(x) {
         s=" B   KiB MiB GiB TiB EiB PiB YiB ZiB"
         while (x>=1024 && length(s)>1) 
               {x/=1024; s=substr(s,5)}
         s=substr(s,1,4)
         xf=(s==" B  ")?"%5d   ":"%8.2f"
         return sprintf( xf"%s\n", x, s)
      }
      {gsub(/^[0-9]+/, human($1)); print}'

답변1

POSIX에는 그런 것이 없지만 최신 GNU coreutils에는 숫자 포맷터가 있습니다:numfmt적어도 예제 출력에 가깝습니다. GNU coreutils ≥8.24(2015년, 지원 수명이 매우 긴 가장 오래된 버전을 제외한 모든 비임베디드 Linux에 존재):

$ numfmt --to=iec-i --suffix=B --format="%9.2f" 1 177152 48832200 1975684956
    1.00B
173.00KiB
 46.58MiB
  1.84GiB

많은 오래된 GNU 도구가 이 형식을 생성할 수 있습니다.GNU 정렬은 숫자를 단위로 정렬할 수 있습니다.coreutils 7.5 기준(2009년 8월, 거의 모든 비임베디드 Linux 배포판에 있음).


코드가 약간 복잡하다고 생각합니다. 다음은 더 깔끔한 awk 버전입니다(출력 형식이 정확히 동일하지 않음).

awk '
    function human(x) {
        if (x<1000) {return x} else {x/=1024}
        s="kMGTEPZY";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {sub(/^[0-9]+/, human($1)); print}'

(보다 전문적인 질문에서 다시 게시)

답변2

v.로 시작하며 다음을 포함합니다 8.21.coreutilsnumfmt:

numfmt다양한 표현으로 숫자를 읽고 필요에 따라 형식을 다시 지정합니다.
가장 일반적인 사용법은 숫자를 숫자로 변환하는 것입니다. 인류표현하다.

예를 들어

printf %s\\n 5607598768908 | numfmt --to=iec-i
5.2 티타늄

그 외 다양한 예제 제공(필터링, 입출력 처리 등 포함)여기.


또한 coreutilsv. 로 시작하면 8.24유사한 numfmt필드 범위 사양으로 여러 필드를 처리할 수 있으며 cut옵션을 사용하여 출력 정밀도 설정을 지원합니다.--format

numfmt --to=iec-i --field=2,4 --format='%.3f' <<<'tx: 180000 rx: 2000000'
보내기: 175.782Ki 받기: 1.908Mi

답변3

이것은 bash 전용 옵션이며, 내장되지 않은 다른 옵션이 없거나 bc다른 옵션, + 십진 형식 및 이진 단위가 없습니다.

# Converts bytes value to human-readable string [$1: bytes value]
bytesToHumanReadable() {
    local i=${1:-0} d="" s=0 S=("Bytes" "KiB" "MiB" "GiB" "TiB" "PiB" "EiB" "YiB" "ZiB")
    while ((i > 1024 && s < ${#S[@]}-1)); do
        printf -v d ".%02d" $((i % 1024 * 100 / 1024))
        i=$((i / 1024))
        s=$((s + 1))
    done
    echo "$i$d ${S[$s]}"
}

예:

$ bytesToHumanReadable 123456789
117.73 MiB

$ bytesToHumanReadable 1000000000000 # '1TB of storage'
931.32 GiB                           #  1TB of storage

$ bytesToHumanReadable 
0 Bytes

$ bytesToHumanReadable 9223372036854775807
7.99 EiB

모든 Bash 버전(Windows용 MSYSGit의 Bash 포함)에서 잘 작동해야 합니다.

답변4

이것은 Peter.O가 Gilles의 awk 스크립트를 수정한 버전에서 영감을 받아 완전히 재작성된 것입니다.

다양성:

  • 4자보다 긴 문자열을 찾아야 하는데 1자보다 긴 문자열을 찾는 Peter.O의 버그를 수정했습니다. 이 버그로 인해 그의 코드는 ZiB 장치에서 작동하지 않습니다.
  • 공간으로 구분된 단위 크기의 매우 보기 흉한 하드코딩된 긴 목록을 제거합니다.
  • 패딩을 활성화/비활성화하는 명령줄 스위치가 추가되었습니다.
  • 기본 1024(KiB)에서 기본 1000(KB) 표기법으로 변환하기 위한 명령줄 스위치가 추가되었습니다.
  • 사용하기 쉬운 하나의 기능으로 모든 것을 통합하세요.
  • 나는 그것을 공개 도메인에 두고 광범위한 사용을 환영합니다.

암호:

bytestohuman() {
    # converts a byte count to a human readable format in IEC binary notation (base-1024), rounded to two decimal places for anything larger than a byte. switchable to padded format and base-1000 if desired.
    local L_BYTES="${1:-0}"
    local L_PAD="${2:-no}"
    local L_BASE="${3:-1024}"
    BYTESTOHUMAN_RESULT=$(awk -v bytes="${L_BYTES}" -v pad="${L_PAD}" -v base="${L_BASE}" 'function human(x, pad, base) {
         if(base!=1024)base=1000
         basesuf=(base==1024)?"iB":"B"

         s="BKMGTEPYZ"
         while (x>=base && length(s)>1)
               {x/=base; s=substr(s,2)}
         s=substr(s,1,1)

         xf=(pad=="yes") ? ((s=="B")?"%5d   ":"%8.2f") : ((s=="B")?"%d":"%.2f")
         s=(s!="B") ? (s basesuf) : ((pad=="no") ? s : ((basesuf=="iB")?(s "  "):(s " ")))

         return sprintf( (xf " %s\n"), x, s)
      }
      BEGIN{print human(bytes, pad, base)}')
    return $?
}

테스트 케이스(출력을 보고 싶은 경우):

bytestohuman 1; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";

즐기다!

관련 정보