expr
は括弧が好きではないようです(数学では演算子の優先順位を明示するために使用されます)。
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
演算子の優先順位をbashで表現する方法は?
組み込みのlet
bashを使用する別の方法:
_$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
_
注
@StéphaneChazelasが指摘 のように、bash
では、読みやすくするために_((...))
_を使用してexpr
またはlet
を計算する必要があります。
移植性のために、_ @ Bernhard answer のように$((...))
を使用します。
代わりに算術展開を使用できます。
echo "$(( 3 * ( 2 + 1 ) ))"
9
私の個人的な意見では、これはexpr
を使用するよりも少し良く見えます。
man bash
から
算術展開算術展開では、算術式の評価と結果の置換が可能です。算術展開の形式は次のとおりです。
$((expression))
式は二重引用符内にあるかのように扱われますが、括弧内の二重引用符は特別に扱われません。式内のすべてのトークンは、パラメーター展開、文字列展開、コマンド置換、引用符の削除を受けます。算術展開は入れ子にすることができます。
評価は、以下の算術評価の下にリストされているルールに従って実行されます。式が無効な場合、bashは失敗を示すメッセージを出力し、置換は行われません。
最近のシェルで算術演算にexpr
を使用する理由はありません。
POSIXは$((...))
拡張演算子を定義しています。そのため、すべてのPOSIX準拠シェル(最新のUnixライク、ダッシュ、bash、yash、mksh、zsh、posh、kshなどのsh
)でそれを使用できます。
_a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
_
ksh
には、let
のように、同じ種類の算術式が渡され、何かに展開されず、式が0に解決されるかどうかに基づいて終了ステータスを返すexpr
ビルトインも導入されました。
_if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
_
ただし、引用符を使用すると読みにくくなり、読みにくくなります(もちろん、expr
と同じ程度ではありません)。ksh
には、_((...))
_の代替形式も導入されています。
_if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
_
これはより読みやすく、代わりに使用する必要があります。
let
および_((...))
_は、ksh
、zsh
、およびbash
でのみ使用できます。他のシェルへの移植性が必要な場合は、$((...))
構文をお勧めします。expr
は、POSIX以前のBourneのようなシェル(通常はBourneシェルまたは初期バージョンのAlmquistシェル)でのみ必要です。
Bourne以外のフロントでは、算術演算子が組み込まれたシェルがいくつかあります。
csh
/tcsh
(実際には、算術評価が組み込まれた最初のUnixシェル):
_@ a = 3 * (2 + 1)
_
akanga
(rc
に基づく)
_a = $:'3 * (2 + 1)'
_
歴史ノートとして、1989年にusenetに投稿されたAlmquistシェルのオリジナルバージョンには、expr
ビルトイン(実際にはtest
とマージされました)がありましたが、後で削除されました。
expr
は外部コマンドであり、特別なシェル構文ではありません。したがって、expr
でシェルの特殊文字を表示するには、引用符で囲んでシェルの解析から保護する必要があります。さらに、expr
では、各数値と演算子を個別のパラメーターとして渡す必要があります。したがって:
_expr 3 \* \( 2 + 1 \)
_
1970年代または1980年代のアンティークUNIXシステムで作業しているのでない限り、expr
を使用する理由はほとんどありません。昔は、シェルには算術を実行する組み込みの方法がなく、代わりにexpr
ユーティリティを呼び出す必要がありました。すべてのPOSIXシェルには、 算術展開 構文による算術が組み込まれています。
_echo "$((3 * (2 + 1)))"
_
構文$((…))
は、算術式の結果(10進数で記述)に展開されます。ほとんどのシェルと同様に、bashは2を法とする整数演算のみをサポートします。64 (または2を法とする32 古いバージョンのbashおよび32ビットマシン上のその他のシェルの場合)。
Bashは 追加の便利な構文 を提供します。これは、割り当てを実行する場合、または式が0かどうかをテストしたいが結果には関心がない場合に使用します。この構成体はkshとzshにも存在しますが、単純なshには存在しません。
_((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
_
整数演算に加えて、expr
はいくつかの文字列操作関数を提供します。これらも、POSIXシェルの機能に含まれていますが、1つを除いて:_expr STRING : REGEXP
_は、文字列が指定された正規表現と一致するかどうかをテストします。 POSIXシェルはこれを外部ツールなしで行うことはできませんが、bashは_[[ STRING =~ REGEXP ]]
_( 別の正規表現構文 を使用することで可能です-expr
はクラシックツールであり、bashはEREを使用します)。
20年前のシステムで実行されるスクリプトを保守しているのでない限り、expr
が存在していたことを知る必要はありません。シェル演算を使用します。
括弧と引用符を使用します。
expr 3 '*' '(' 2 '+' 1 ')'
9
引用符は、bashが括弧をbash構文として解釈しないようにします。
あなたがBCを持っているなら...
echo '3 * (2 + 1)'|bc
9