Was wäre der beste Weg, um zu überprüfen, ob $ 1 eine Ganzzahl in / bin / dash ist?
In Bash könnte ich tun:
[[ $1 =~ ^([0-9]+)$ ]]
Dies scheint jedoch nicht POSIX-konform zu sein, und Dash unterstützt dies nicht
Was wäre der beste Weg, um zu überprüfen, ob $ 1 eine Ganzzahl in / bin / dash ist?
In Bash könnte ich tun:
[[ $1 =~ ^([0-9]+)$ ]]
Dies scheint jedoch nicht POSIX-konform zu sein, und Dash unterstützt dies nicht
Antworten:
Die folgenden Funktionen erkennen positive oder negative Ganzzahlen und arbeiten unter dash
und sind POSIX:
echo "$1" | grep -Eq '^[+-]?[0-9]+$' && echo "It's an integer"
case "${1#[+-]}" in
''|*[!0-9]*)
echo "Not an integer" ;;
*)
echo "Integer" ;;
esac
Oder mit ein wenig Gebrauch des :
(nop) -Befehls:
! case ${1#[+-]} in *[!0-9]*) :;; ?*) ! :;; esac && echo Integer
Ob dash
, bash
, ksh
, zsh
, POSIX sh
oder posh
( "a Reimplementation der Bourne - Shell" sh
); Das case
Konstrukt ist das am weitesten verbreitete und zuverlässigste:
case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac
dash
? Es funktioniert bei mir unter bash
aber nicht dash
.
dash
; Um das Ergebnis abzufragen, habe ich echo $?
nach dem case-Befehl hinzugefügt .
posh
("eine Neuimplementierung der Bourne-Shell") hat mit dieser Lösung allerdings auch kein Problem.
case
. Ein Grund ist der Fehler, den Sie beschreiben, ein anderer, der in Editoren mit Funktionen, die auf übereinstimmende Klammern (vim) angewiesen sind, eine viel bessere Unterstützung bietet, und nicht zuletzt finde ich es persönlich besser lesbar, wenn sie übereinstimmen. - WRT posh
ist POSIX; Nun, das Zitat aus der Manpage, das ich gegeben habe, deutete auf etwas anderes hin, aber man kann sich sowieso nicht auf solche informellen Aussagen verlassen, denke ich. Die alte Borowski-Shell ist sowieso nicht mehr so bedeutend, seit wir uns in der POSIX-Ära befinden.
Sie können den -eq
Test für die Zeichenfolge mit sich selbst verwenden:
$ dash -c 'a="a"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi'
dash: 1: [: Illegal number: a
not a number
$ dash -c 'a="0xa"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi'
dash: 1: [: Illegal number: 0xa
not a number
$ dash -c 'a="-1"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi'
number
Wenn die Fehlermeldung ein Problem darstellt, leiten Sie die Fehlerausgabe weiter an /dev/null
:
$ dash -c 'a="0xa"; [ "$a" -eq "$a" ] 2>/dev/null|| echo no'
no
" 023 "
das eine Zahl ist. Beachten Sie, dass dies mit Bindestrich funktioniert, jedoch nicht mit allen anderen POSIX-Shells, da das Verhalten nicht spezifiziert ist, wenn die Operanden Dezimalzahlen sind. Zum Beispiel mit ksh würde es sagen, dass SHLVL
oder 1+1
eine Zahl ist.
Versuchen Sie, es als arithmetische Erweiterung zu verwenden, und prüfen Sie, ob es funktioniert. Eigentlich muss man etwas strenger sein, weil arithmetische Erweiterungen zum Beispiel führende und nachfolgende Leerzeichen ignorieren würden. Führen Sie also eine arithmetische Erweiterung durch und stellen Sie sicher, dass das erweiterte Ergebnis genau mit der ursprünglichen Variablen übereinstimmt.
check_if_number()
{
if [ "$1" = "$((${1}))" ] 2>/dev/null; then
echo "Number!"
else
echo "not a number"
fi
}
Dies würde auch negative Zahlen akzeptieren - wenn Sie sie wirklich ausschließen möchten, fügen Sie einen zusätzlichen Scheck für hinzu $((${1} >= 0))
.
[[
$(( ... ))
? Wenn ja, sollte meine Antwort immer noch sachlich korrekt sein, ich muss nur ein zusätzliches Zitat hinzufügen.
check_if_number 1.2
und die Funktion zurückgegeben: dash: 3: arithmetic expression: expecting EOF: "1.2"
Vielleicht mit expr
?
if expr match "$1" '^\([0-9]\+\)$' > /dev/null; then
echo "integer"
else
echo "non-integer"
fi
match
noch \+
sind POSIX. Es würde auch sagen, dass 0 keine Zahl ist. Sie wollenexpr "x$1" : 'x[0-9]\{1,\}$'
Im POSIX-System können Sie expr verwenden :
$ a=a
$ expr "$a" - 0 >/dev/null 2>&1
$ [ "$?" -lt 2 ] && echo Integer || echo Not Integer
expr
Implementierungen werden sagen, dass 9999999999999999999 keine ganze Zahl ist. POSIX gibt keine Garantie, dass dies funktioniert. In der Praxis wird zumindest auf einem GNU-System gesagt, dass "Länge" eine ganze Zahl ist.
expr 9999999999999999999 + 0
gibt mir ein 3 Exit - Status und expr -12 + 0
und expr length + 0
geben Sie mir eine 0 Exit - Status mit GNU ausdr ( + string
Kräfte string
als String mit GNU berücksichtigt werden expr
. expr "$a" - 0
Besser funktionieren würde).
-12
ist eine gültige Ganzzahl und 9999999999999999999
gab einen Überlauf.
Hier ist eine einfache Funktion, die dieselbe Methode wie die Antwort von muru verwendet :
IsInteger() # usage: IsInteger string
{ # returns: flag
[ "$1" -eq "$1" ] 2> /dev/null
}
Beispiel:
p= n=2a3; IsInteger $n || p="n't" ; printf "'%s' is%s an integer\n" "$n" "$p"
p= n=23; IsInteger $n || p="n't" ; printf "'%s' is%s an integer\n" "$n" "$p"
Ausgabe:
'2a3' isn't an integer
'23' is an integer
foo\n123\nbar
ist keine ganze Zahl, würde aber diesen Test bestehen.