6

タイトルは本当にそれをすべて言いますが、私は現在、ケースステートメントを含む単純な関数を使用して、人間が読めるファイルサイズの文字列をバイト単位のサイズに変換しています。十分に機能しますが、他のコードに移植するには少し扱いに​​くいので、代わりにシェルスクリプトで使用できる広く利用可能なコマンドがあるかどうか知りたいですか?

基本的には「100g」や「100gb」などの文字列をバイトに変換したい。

現在、次のことを行っています。

to_bytes() {
    value=$(echo "$1" | sed 's/[^0123456789].*$//g')
    units=$(echo "$1" | sed 's/^[0123456789]*//g' | tr '[:upper:]' '[:lower:]')

    case "$units" in
        t|tb)   let 'value *= 1024 * 1024 * 1024 * 1024'    ;;
        g|gb)   let 'value *= 1024 * 1024 * 1024'   ;;
        m|mb)   let 'value *= 1024 * 1024'  ;;
        k|kb)   let 'value *= 1024' ;;
        b|'')   let 'value += 0'    ;;
        *)
                value=
                echo "Unsupported units '$units'" >&2
        ;;
    esac

    echo "$value"
}

ファイルを操作するスクリプトではかなり一般的だと私が思っていたのは、少しやり過ぎのようです。これをより迅速に行うための何かが存在する可能性があるほど十分に一般的です。

広く利用可能なソリューションがない場合 (つまり、unix と linux のフレーバーの大部分)、上記の関数を最適化するためのヒントをいただければ幸いです。関数を小さくして再利用しやすくしたいからです。

4

6 に答える 6

2

ここに私が書いたものがあります。kKB、および をサポートしていますKiB。(ただし、1KB = 1000 バイト、1KiB = 1024 バイトのように、2 の累乗と 10 の累乗のサフィックスを区別しません。)

#!/bin/bash

parseSize() {(
    local SUFFIXES=('' K M G T P E Z Y)
    local MULTIPLIER=1

    shopt -s nocasematch

    for SUFFIX in "${SUFFIXES[@]}"; do
        local REGEX="^([0-9]+)(${SUFFIX}i?B?)?\$"

        if [[ $1 =~ $REGEX ]]; then
            echo $((${BASH_REMATCH[1]} * MULTIPLIER))
            return 0
        fi

        ((MULTIPLIER *= 1024))
    done

    echo "$0: invalid size \`$1'" >&2
    return 1
)}

ノート:

  • =~という名前の配列に一致を格納するbash の正規表現演算子を活用しBASH_REMATCHます。
  • 関数本体を囲む括弧が巧妙に隠されていることに注意してください。それらはshopt -s nocasematch、関数から漏れないようにするためにあります。
于 2013-07-12T13:30:48.773 に答える