bashの引数文字列から整数へ


74

算術演算を実行するために引数を整数に変換する方法を理解し、それを出力する、例えばaddOne.sh

echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1

私はあなたの質問をフォーマットしようとしますが、それはどういうわけか不明瞭なままです。printf "1 + %s\n" $1 won't do ?
アルケマール

回答:


89

bashでは、「引数を整数に変換して算術演算を実行する」ことはありません。bashでは、変数はコンテキストに応じて整数または文字列として扱われます。

算術演算を実行するには、算術展開演算子を呼び出す必要があります$((...))。例えば:

$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3

または一般的に好ましい:

$ echo "$((a + 1))"
3

bsh(ksh93、zsh、またはyashとは対照的に)は整数演算のみを実行することに注意してください。浮動小数点数(10進数の数値)がある場合は、他の支援ツールがあります。たとえば、次を使用しますbc

$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14

または、bashの代わりに浮動小数点演算をサポートするシェルを使用できます。

zsh> echo $((3.14 + 1))
4.14

文字列が何であるかわからない場合(ユーザー入力など)、$(())または(())を使用しても安全ではありません。これを考慮してください:foo = foo((foo + = 0))fooを再帰的に評価しようとすると、スクリプトがクラッシュします。同じ:foo = foo foo = $((foo + 0))
art

12

他の方法では、使用できます expr

例:

$ version="0002"
$ expr $version + 0
2
$ expr $version + 1
3

10

ではbashprintf -vを使用して、あらゆるものから整数への変換を実行できます。

printf -v int '%d\n' "$1" 2>/dev/null

浮動小数点数は整数に変換されますが、数値は0に変換されるようには見えません。べき乗は前の数値に切り捨てられます e

例:

$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1

2
なし他のシェルではprintf -v、このコマンド置換で達成することができます:int="$(printf '%d' 123.123 2>/dev/null)"
エイドリアン・ギュンター

2
これはbashでは機能しません。
マイケルマルティネス

@MichaelMartinezよろしいですか?bash使用しているバージョンは何ですか?
cuonglm

GNU bash、バージョン4.2.46(1)-release(x86_64-redhat-linux-gnu)
Michael Martinez

5

Linux環境とOSX環境の両方で実行するbashスクリプトを開発しているときに、同様の状況が最近発生しました。OSXの1つのコマンドの結果は、結果コードを含む文字列を返しました。すなわち、" 0"。もちろん、これは次の場合に正しくテストできませんでした:

if [[ $targetCnt != 0 ]]; then...

解決策は、上記の@ John1024の回答と同様に、結果を強制的に整数に変換(つまり「変換」)して、期待どおりに動作させることでした。

targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...

3
==など[[[別名test)で文字列比較を行います。たとえば、算術比較にはさまざまな演算子があり[[ $targetcnt -ne 0 ]]ます。条件式のマンページ(または情報)を参照してください。スペースを具体的にトリミングするには[、引用符で囲まれていない変数展開[ $targetcnt == 0 ]を使用してデフォルトの単語分割を行います(では行われません[[)が、一般的にそのアプローチは危険をもたらします。
-dave_thompson_085

-2

トレース(-x)が表示されない場合でも、カラーコードに注意してください。それが与えるのは、数字であるはずの文字列が、印刷方法に関係なく引用符で囲まれていることです。


1
私はあなたの答えが少し不明瞭だと思うので、投票しました。おそらく、スクリプトの修正対象を追加できますか?
Time4Tea

これは、bash + integer + stringの検索におけるトップアンサーであったため、アンサーに含まれていない情報に関連する情報を追加しました。つまり、ストリングがカラーコードでラップされている$((var+var))場合、ただし、あなたechoまたはprintf両方の変数が同じ場合。出力のソースでカラーコードを無効にすることで修正することしかできなかったため、修正を知りません。トレースログにそれを発見するには、割り当てられたとして、問題の変数が表示されますvar='0'、それは単純にする必要がありながらvar=0
untore

sed無効にできない場合は、出力にカラーコードが含まれていないことを確認してください
18
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.