このbashスクリプトを持っていますが、16行目で問題がありました。15行目の前の結果を取得して、16行目の変数に追加するにはどうすればよいですか。
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in `ls output-$i-*`; do
echo "$j"
metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
num= $num + $metab (line16)
done
echo "$num"
done
整数の場合 :
算術展開を使用します :$((EXPR))
num=$((num1 + num2))
num=$(($num1 + $num2)) # also works
num=$((num1 + 2 + 3)) # ...
num=$[num1+num2] # old, deprecated arithmetic expression syntax
外部のexpr
ユーティリティを使う。これは本当に古いシステムにのみ必要であることに注意してください。
num=`expr $num1 + $num2` # whitespace for expr is important
浮動小数点の場合 :
Bashはこれを直接サポートしていませんが、使用できる外部ツールがいくつかあります。
num=$(awk "BEGIN {print $num1+$num2; exit}")
num=$(python -c "print $num1+$num2")
num=$(Perl -e "print $num1+$num2")
num=$(echo $num1 + $num2 | bc) # whitespace for echo is important
科学的記数法を使うこともできます(例:2.5e+2
)
よくある落とし穴 :
変数を設定するとき、=
の両側に空白を入れることはできません。そうしないと、シェルが最初のWordを実行するアプリケーションの名前として解釈するように強制します(例:num=
またはnum
)
num= 1
num =2
bc
とexpr
はそれぞれの数と演算子を別々の引数として扱うので、空白が重要です。 3+
+4
のような引数を処理することはできません。
num=`expr $num1+ $num2`
$(( ))
算術展開を使用してください。
num=$(( $num + $metab ))
詳細については http://tldp.org/LDP/abs/html/arithexp.html を参照してください。
やり方は千通りあります。これはdc
を使ったものです:
dc <<<"$num1 $num2 + p"
しかし、それがあなたには強すぎる(あるいは移植性の問題)なら、あなたは言うことができます
echo $num1 $num2 + p | dc
しかし、多分あなたはRPNが風変わりで奇妙であると思うそれらの人々のうちの1人です。心配しないで! bc
はあなたのためにここにあります:
bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc
とは言っても、あなたがあなたのスクリプトにすることができるいくつかの無関係な改善があります
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in output-$i-* ; do # for can glob directly, no need to ls
echo "$j"
# grep can read files, no need to use cat
metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}')
num=$(( $num + $metab ))
done
echo "$num"
done
編集:
BASH FAQ 022 で説明されているように、bashは浮動小数点数をネイティブにサポートしません。浮動小数点数を合計する必要がある場合は、外部ツール(bc
やdc
など)を使用する必要があります。
この場合、解決策は
num=$(dc <<<"$num $metab + p")
浮動小数点数の累積数をnum
に追加します。
Bashで、
num=5
x=6
(( num += x ))
echo $num # ==> 11
Bashは整数算術しか扱えないので、あなたのawkコマンドが小数を返すなら、あなたは再設計したくなるでしょう。
num=0
for ((i=1; i<=2; i++)); do
for j in output-$i-*; do
echo "$j"
num=$(
awk -v n="$num" '
/EndBuffer/ {sum += $2}
END {print n + (sum/120)}
' "$j"
)
done
echo "$num"
done
私はグーグルに来るように私はいつも構文を忘れる、それから私は私がなじみのあるものを見つけることは決してない。これは私にとって最もクリーンで、私が他の言語で期待していることにもっと忠実です。
i=0
((i++))
echo $i;
私もこの方法がとても好きです。
count=$[count+1]
#!/bin/bash
read X
read Y
echo "$(($X+$Y))"
Metabを整数として宣言してから算術評価を使用する必要があります。
declare -i metab num
...
num+=metab
...
詳細については https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html#Shell-Arithmetic を参照してください。
便利なすべての算術演算子のために.bashrc
の中の関数として定義することができるPOSIX
で行う別の移植性のあるbash
準拠の方法。
addNumbers () {
local IFS='+'
printf "%s\n" "$(( $* ))"
}
そして単にコマンドラインで以下のように呼び出します。
addNumbers 1 2 3 4 5 100
115
アイデアは、 入力フィールド区切り文字(IFS) を使用することです。これは、展開後の単語分割に使用されるbash
内の特殊変数と、行を単語に分割するためのものです。この関数は、値をローカルに変更して、和演算子+
として単語分割文字を使用します。
IFS
はローカルに変更され、NOTは関数の範囲外のデフォルトのIFS
の動作に影響します。 man bash
ページからの抜粋
シェルはIFSの各文字を区切り文字として扱い、他の展開の結果をこれらの文字の単語に分割します。 IFSが設定されていない場合、またはその値がデフォルト値の場合は、前の展開の結果の先頭と末尾の、、、とのシーケンスは無視され、先頭または末尾以外のIFS文字のシーケンスは区切り文字として機能します。言葉.
"$(( $* ))"
は+
で分割されるために渡された引数のリストを表し、後で合計値はprintf
関数を使って出力されます。他の算術演算にも範囲を追加するように関数を拡張することができます。
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in `ls output-$i-*`; do
echo "$j"
metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
let num=num+metab (line 16)
done
echo "$num"
done