標準的な解決策:
expr $d1 - $d2
次のこともできます:
echo $(( d1 - d2 ))
ただし、これは 07
を扱うことに注意してください 8進数として! (だから 07
7
と同じです 、しかし 010
10
とは異なります ).
これらはいずれも、シェル コマンド ラインから機能します。 bc
ただし、おそらく最も簡単な解決策です。
bc:の使用
$ echo "$d1 - $d2" | bc
awk
の使用 :
$ echo $d1 $d2 | awk '{print $1 - $2}'
perl
の使用 :
$ perl -E "say $d1 - $d2"
Python
の使用 :
$ python -c "print $d1 - $d2"
すべて戻る
4
OP のケースに限定されない回答
質問のタイトルは人々をここに導くので、OP で説明されているケースが非常に限られているため、他のすべての人のためにその質問に答えることにしました.
TL;DR
ようやく関数を書くことに落ち着きました。
<オール>0
int 以外の場合:int(){ printf '%d' ${1:-} 2>/dev/null || :; }
- 必要に応じて [empty_string] int 以外の場合:
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
- 最初の int または [empty_string] を見つけたい場合 :
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
- 最初の int または 0 を見つけたい場合:
# This is a combination of numbers 1 and 2
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
int 以外でゼロ以外のステータス コードを取得する場合は、||:
を削除します。 (別名または true
) ただし、;
は残します
テスト
# Wrapped in parens to call a subprocess and not `set` options in the main bash process
# In other words, you can literally copy-paste this code block into your shell to test
( set -eu;
tests=( 4 "5" "6foo" "bar7" "foo8.9bar" "baz" " " "" )
test(){ echo; type int; for test in "${tests[@]}"; do echo "got '$(int $test)' from '$test'"; done; echo "got '$(int)' with no argument"; }
int(){ printf '%d' ${1:-} 2>/dev/null||:; };
test
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
test
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
test
int(){ printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null)||:; }
test
# unexpected inconsistent results from `bc`
int(){ bc<<<"${1:-}" 2>/dev/null||:; }
test
)
テスト出力
int is a function
int ()
{
printf '%d' ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '0' from '6foo'
got '0' from 'bar7'
got '0' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument
int is a function
int ()
{
expr 0 + ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '' from 'bar7'
got '' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
int is a function
int ()
{
expr ${1:-} : '[^0-9]*\([0-9]*\)' 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
int is a function
int ()
{
printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null) || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument
int is a function
int ()
{
bc <<< "${1:-}" 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '0' from 'bar7'
got '' from 'foo8.9bar'
got '0' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
注意
受け入れられた回答が set -o nounset
と互換性がないため、このうさぎの穴に送られました (別名 set -u
)
# This works
$ ( number="3"; string="foo"; echo $((number)) $((string)); )
3 0
# This doesn't
$ ( set -u; number="3"; string="foo"; echo $((number)) $((string)); )
-bash: foo: unbound variable