Die Standardlösung:
expr $d1 - $d2
Sie können auch Folgendes tun:
echo $(( d1 - d2 ))
aber beachten Sie, dass dies 07
behandeln wird als Oktalzahl! (also 07
ist dasselbe wie 7
, aber 010
ist anders als 10
).
Jede davon funktioniert über die Shell-Befehlszeile. bc
ist jedoch wahrscheinlich die einfachste Lösung.
Verwendung von bc:
$ echo "$d1 - $d2" | bc
Mit awk
:
$ echo $d1 $d2 | awk '{print $1 - $2}'
Mit perl
:
$ perl -E "say $d1 - $d2"
Mit Python
:
$ python -c "print $d1 - $d2"
alle zurück
4
Eine Antwort, die nicht auf den Fall des OP beschränkt ist
Der Titel der Frage führt die Leute hierher, also habe ich beschlossen, diese Frage für alle anderen zu beantworten, da der beschriebene Fall des OP so begrenzt war.
TL;DR
Ich habe mich schließlich dafür entschieden, eine Funktion zu schreiben.
- Wenn Sie
0
möchten bei non-int:
int(){ printf '%d' ${1:-} 2>/dev/null || :; }
- Wenn Sie [empty_string] wollen bei non-int:
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
- Wenn Sie wollen, finden Sie das erste int oder [empty_string] :
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
- Wenn Sie das erste Int oder 0 suchen möchten:
# This is a combination of numbers 1 and 2
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
Wenn Sie einen Nicht-Null-Statuscode auf non-int erhalten möchten, entfernen Sie ||:
(auch bekannt als true
), aber belassen Sie die ;
Tests
# 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
)
Testausgabe
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
Hinweis
Ich wurde in dieses Kaninchenloch geschickt, weil die akzeptierte Antwort nicht mit set -o nounset
kompatibel ist (auch bekannt als 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