1. 概要

数値の計算は、bashスクリプトで役立つことがよくあります。 ただし、プロセスは必ずしも簡単ではありません。

このチュートリアルでは、bashで算術演算を実行するいくつかの方法を学習します。

2. bashの変数

bashには型システムがありません—すべての変数は文字列です。そのため、他のほとんどの言語のように単純に算術演算を書くことはできません。 デフォルトでは、数値ではなく文字列に対する操作として解釈されます。

2.1. 変数の宣言

属性なしでdeclareコマンドを使用して変数を宣言することから始めましょう。

$ declare A=2+2
$ echo $A
2+2

ご覧のとおり、文字列ベースの型システムはこれをテキストの宣言として扱いました。

2.2. 整数属性

この式を算術として解釈したい場合は、それを明示的に記述する必要があります。 1つの方法は、-i属性を使用して変数を宣言することです。

$ declare -i A=2+2
$ echo $A
4

変数がまだ文字列であることを忘れてはなりません。 -i フラグは、この変数への割り当て時にすべての式が整数として解析されることを示します。

解析エラーが発生した場合、結果はデフォルトでゼロになります。 同様に、数値の小数部分も削除されます。

$ A=test
$ echo $A
0

2.3. letコマンド

または、 let コマンドを使用すると、変数を宣言して、割り当て中に算術演算を実行できます。 ここでの違いは、変数を後で整数以外のものに再割り当てできることです。

$ let A=2+2
$ echo $A
4
$ A=test
$ echo $A
test

3. パラメータ拡張

変数を作成したので、それらの値にアクセスする方法が必要です。 また、宣言なしで、式の値をオンザフライで取得したい場合もあります。

パラメーター展開を使用すると、式をその値に置き換えることができます。変数から値を取得し、コマンドを呼び出し、算術演算を実行するために使用します。

3.1. 可変置換

ドル記号($)を使用して、変数の値にアクセスできます。

$ A=2
$ echo $A
2

さらに、中括弧を使用して、変数の名前を式の残りの部分から分離することができます。

$ echo ${A}string
2string

3.2. 算術拡張

算術演算の値は、変数として宣言せずに、二重括弧で囲むことで取得できます。

$ A=2;B=2
$ echo $((A+B+1))
5

3.3. カウントラインの例

この知識を有効に活用するために、左側に行番号が付いたファイルの内容を印刷するスクリプトを作成しましょう。

まず、入力用の変数とラインカウンター用の変数を宣言します。

declare input=$1
declare -i counter=1

次に、行番号にパディングを追加して、その長さが一定になるようにします。 これを実現するには、 wc コマンドを使用してファイル内の行数をカウントし、結果の数の長さをチェックしてパッドサイズを示します。

declare -i lines=`wc -l < $input`
declare -i pad=${#lines}

ここでは、 wc コマンドの結果を、コマンドをバッククォートで囲むことにより、lines内に保存しました。 次に、 $ {}構文でのパラメーター展開とlines の前のハッシュ演算子の両方を使用して、padを割り当てました。その値の長さ。

ここで、ファイルの行を繰り返し処理し、パディングを使用してカウンターを印刷し、行を印刷する必要があります。 最後に、算術展開内でインクリメント演算子(++)を使用してカウンターをインクリメントします。

while IFS= read -r line
do
  printf "%+${pad}s" $counter
  echo "| $line"
  ((counter++))
done < "$input"

完全なスクリプトは次のとおりです。

#!/bin/bash
declare input=$1
declare -i counter=1
declare -i lines=`wc -l < $input`
declare -i pad=${#lines}

while IFS= read line
do
  printf "%+${pad}s" $counter
  echo "| $line"
  ((counter++))
done < "$input"

最初の4行をそれ自体に通して試してみましょう。 まず、最初の4行を一時ファイルにリダイレクトします。

$ head -4 lines_padding.sh > tmp

次に、スクリプトを実行します。

$ ./lines_padding.sh tmp
1| #!/bin/sh
2| declare input=$1
3| declare -i counter=1
4| declare -i lines=`wc -l < $input`

4. exprコマンド

bash の組み込み機能を使用する代わりに、外部のexprコマンドを使用できます。 それは仕事をするのに最も強力なプログラムではありませんが、広く使われています。 また、POSIX標準の一部です。 exprは、ブール式に加えて算術式を解析します。文字列に対していくつかのマッチングおよびサブストリング操作を実行することもできます。

$ expr 2 + 3
5
$ expr 2 \< 3
1
$ expr substr Baeldung 1 4
Bael

「<」のような多くの文字はエスケープする必要があることに注意してください。 組み込みのbash機能を使用する場合、エスケープは必要ありません。 また、BSD/macOSバージョンのexprは、算術演算とブール演算のみに制限されています。

5. bcコマンド

bcコマンドはexprに似ていますが、はるかに強力です。 これはPOSIX標準の一部でもあります。 最も重要なことは、bcは浮動小数点演算を可能にすることです。 さらに、より幅広い演算子を使用し、単純なスクリプト言語を提供します。

5.1. 浮動小数点演算

スケール(小数点以下の最大桁数)を定義すると、任意の精度で浮動小数点演算を実行できます。

$ echo "scale=2;4/3" | bc
1.33

5.2. スクリプト機能

bc は、変数の宣言、ループの記述、および条件ステートメントの記述を可能にする、単純なCのようなスクリプト言語を解析することもできます。 1から10の範囲の偶数を出力するスクリプトを書いてみましょう。

$ echo "for(i=1; i<=10; i++) {if (i % 2 == 0) i;}" | bc
2
4
6
8
10

5.3. 組み込み関数

いくつかの組み込みの数学関数もあります。 たとえば、4のスケールで10の平方根を取得できます。

$ echo "scale=4;sqrt(10)" | bc
3.1622

6. 結論

この記事では、最初にbashの内部機能を使用して数値処理を実行する方法を説明しました。

次に、 bash スクリプトから呼び出して、より複雑な処理を実行できる追加のコマンドをいくつか確認しました。

算術演算を実行し、その結果を保存および印刷するためのいくつかのユースケースを試しました。