非変数に割り当ててみますか?

非変数に割り当ててみますか?

シェルスクリプト関数で算術演算を使用できます。

function mess
{
   if (( "$1" > 0 )) ; then
      total=$1
   else
      total=100
   fi
   tail -$total /var/adm/messages | more
}

関数argsに対して算術演算を実行しようとしています。

#!/bin/bash
byte="Bytes"
kilo="KB"
mega="MB"
giga="GB"
function bytesToUnites() {
if (( "$1" < 1000 )) 
then
    echo $1" "$byte
elif (( $1 < 1000000 ))
then
    let $1/=1000
    echo $1" "$kilo
fi
}

bytesToUnites 28888

ただし、次のエラーが発生します。

line 12: let: 28888/=1000: attempted assignment to non-variable (error token is "/=1000")
28888 KB

この問題をどのように解決できますか?

答え1

問題は、あなたが実行しようとしていることですパラメータの置換最初の位置パラメータ名の前に$

次のような目的を達成できます。

...
elif [ $1 -lt 1000000 ]
then
    arg="$1"
    let arg/=1000
    echo $arg" "$kilo
fi

私が知っている限り、位置パラメータを直接使用することはできません。

let 1/=1000

これは構文エラーだからです。

しかし、エラーメッセージを見ると、$1.Bash28888は浮動小数点演算を実行しないことに注意してください。arg設定が2828.888ではない(28888を整数1000で割った商)ということがわかります。よりこのクールなQ&Aスクリプトで浮動小数点演算を実行する方法について説明します。

答え2

位置パラメータに値を割り当てる唯一の方法は、組み込み関数をbash使用することです。set

set a b

aとに割り当てられます(完全な位置引数リストをリセットするので、...$1が失われます)。b$2$3$4

ここでは、次のようにすることができます。

set -- "$(($1 / 1000))"

$11000で割った値を割り当てます$1

これとは対照的に、zsh(GNUプロジェクトの一部ではない高度なBourne様シェルを使用すると、すべてのUnicesで使用できますが、通常はデフォルトでは使用できません)、別々の場所引数を割り当てることができます。たとえば、次のようになります。

1=$(($1 / 1000))

または:

argv[1]=$(($1 / 1000))

または:

(( argv[1] /= 1000 ))

$argv位置パラメータに関連する特別な配列です)

まだ次のことはできません。

let 1/=1000
(( 1/=1000 ))

しかし。

zsh浮動小数点演算もサポートされるので、次のようにすることができます。

((argv[1] /= 1000.))

(浮動小数点演算を強制するには、浮動小数点定数(1000)を使用してください。)

次のように表示できます。

printf "%.2f$kilo\n" $1

答え3

私の2セントの場合は、モジュロを使用することをお勧めします%。セルリストを上に移動し、各ステップで残りを保存します。ここで:

(   
    gb=$(((mb=(kb=1024*(b=1))*kb)*kb))                 #define units 
    set -- 8934752983457                               #your $1 - just a random test
    for u in '' k m g                                  #this part is neat
    do  [ $((c=$1/${u}b)) -ge 1 ] || break             #math eval varnames
        [ "$u" != g ] && c=$(($c%$kb))                 #if not yet g only save %
        set -- $(($1-$c)) "$c${u}b${2:+.$2}"           #decrement $1 - build $2
    done ; shift                                       #done - toss $1
    IFS=. ; printf %s\\n $*                            #split $2 andd print
)

出力

8321gb
140mb
454kb
417b

関連情報