シェルスクリプト関数で算術演算を使用できます。
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
設定が28
28.888ではない(28888を整数1000で割った商)ということがわかります。よりこのクールなQ&Aスクリプトで浮動小数点演算を実行する方法について説明します。
答え2
位置パラメータに値を割り当てる唯一の方法は、組み込み関数をbash
使用することです。set
set a b
a
とに割り当てられます(完全な位置引数リストをリセットするので、...$1
が失われます)。b
$2
$3
$4
ここでは、次のようにすることができます。
set -- "$(($1 / 1000))"
$1
1000で割った値を割り当てます$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