/ bin / dash:$ 1が数字かどうかを確認します


12

$ 1が/ bin / dashの整数かどうかを確認する最良の方法は何でしょうか?

bashでは、次のことができます。

[[ $1 =~ ^([0-9]+)$ ]]

しかし、それはPOSIXに準拠していないようで、ダッシュはそれをサポートしていません

回答:


12

以下は正または負の整数を検出し、dashPOSIXで動作します:

オプション1

echo "$1" | grep -Eq '^[+-]?[0-9]+$' && echo "It's an integer"

オプション2

case "${1#[+-]}" in
    ''|*[!0-9]*)
        echo "Not an integer" ;;
    *)
        echo "Integer" ;;
esac

または、:(nop)コマンドを少し使用して:

! case ${1#[+-]} in *[!0-9]*) :;; ?*) ! :;; esac && echo Integer

5
文字列に改行が含まれる場合はどうなりますか?foo\n123\nbar整数ではありませんが、このテストに合格します。
godlygeek

3
つまり、grepバージョンです。ケースのバージョンは正しいようです。
godlygeek

5

かどうかdashbashkshzsh、POSIX sh、またはposh"Bourneシェルの再実装" sh)。case構築物は、最も広く利用可能性と信頼性です。

case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac

これをテストしましたdashか?それは私の下で動作しますbashが、動作しませんdash
John1024

はい、システムでもテストしましたdash; echo $?caseコマンドの後に追加した結果を調べるために。
ジャニス

私は同じ(Debian安定版)をしましたが、喜びはありませんでした。ダッシュの下で機能する完全な例については、オプション2を参照してください。
John1024

うーん、テスト用に利用できるオリジナルのボーンシェルがありません。「ボーンシェルではない機能(kshで)」について調べたドキュメントでは、少なくとも言及していないので、そこにあったと思います。番号?-次に、先頭の括弧を省略します。-OTOH posh(「Bourneシェルの再実装」)も、このソリューションでは問題ありません。
ジャニス

1
@mikeserv; で常に一致する括弧を使用する理由はいくつかありcaseます。1つの理由は、あなたが説明するバグ、もう1つは一致する括弧(vim)に依存する機能を備えたエディターでは、より優れたサポートを提供することです。-WRT poshはPOSIXです。まあ、私が与えたmanページからの引用は何か他のものを示唆しましたが、とにかくそのような非公式のステートメントに頼ることはできません。とにかく古いボーンシェルは、私たちがPOSIX時代になった今ではそれほど重要ではありません。
ジャニス

1

あなたは-eqそれ自身で文字列のテストを使うことができます:

$ 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

エラーメッセージに問題がある場合は、エラー出力をにリダイレクトします/dev/null

$ dash -c 'a="0xa"; [ "$a" -eq "$a" ] 2>/dev/null|| echo no'
no

1
また、それは" 023 "数字だと言うでしょう。ダッシュで動作しますが、オペランドがノート10進整数の場合の動作は指定されていないため、他のすべてのPOSIXシェルでは動作しないことに注意してください。たとえば、kshの場合、それはSHLVLor 1+1と数字になります。
ステファンシャゼル

0

算術展開として使用してみて、動作するかどうかを確認してください。実際には、算術展開では、たとえば先頭と末尾のスペースが無視されるため、それより少し厳密にする必要があります。したがって、算術展開を行い、展開された結果が元の変数と正確に一致することを確認してください。

check_if_number()
{
    if [ "$1" = "$((${1}))" ] 2>/dev/null; then
        echo "Number!"
    else
        echo "not a number"
    fi
}

これは、負の数も受け入れます。本当に除外する場合は、の追加チェックを追加し$((${1} >= 0))ます。


1
ダッシュがありません[[
グレンジャックマン

@glennjackmanおっと。あります$(( ... ))か?もしそうなら、私の答えはまだ実質的に正しいはずです、私はいくつかの余分な引用符を追加する必要があります。
godlygeek

それはあなたの答えです:調べに行きましょう。
グレンジャックマン

そのように見えるので、私の更新されたバージョンはトリックを行う必要があります。しかし、私はそれをテストするためのダッシュを持っていません-それで、もし私が他に何かを見逃したかどうか知らせてください。
godlygeek

私が試した:check_if_number 1.2と関数が返されました: dash: 3: arithmetic expression: expecting EOF: "1.2"
-John1024

0

おそらくexpr

if expr match "$1" '^\([0-9]\+\)$' > /dev/null; then
  echo "integer"
else 
  echo "non-integer"
fi

POSIX matchでも\+ありません。また、0は数字ではないということです。あなたが欲しいexpr "x$1" : 'x[0-9]\{1,\}$'
ステファンシャゼル

0

POSIXシステムでは、exprを使用できます。

$ a=a
$ expr "$a" - 0 >/dev/null 2>&1
$ [ "$?" -lt 2 ] && echo Integer || echo Not Integer

0は整数ではないと言います(そして、OPのbashソリューションが拒否した-12を言います)。一部のexpr実装では、9999999999999999999は整数ではないと言います。POSIXは、これが機能することを保証しません。実際には、少なくともGNUシステムでは、「長さ」は整数であると言われます。
ステファンシャゼル

私のテストでは、少なくともDebianとOSXで動作します。0を表す整数です。Posixは、exprが算術演算を行うために、$ aが有効な式(整数)でなければならないことを保証します。
クオンルム

ああ、すみません、$のテストを見落としていましたか?<2。はまだexpr 9999999999999999999 + 0私に3終了ステータスを与え、expr -12 + 0そしてexpr length + 0私のGNU exprの0終了ステータスを(与える+ string力はstringGNUの文字列として考えることにするexprexpr "$a" - 0よりよく機能するであろう)。
ステファンシャゼル

@StéphaneChazelas:ああ、はい、私の答えを更新しました。私-12は有効な整数であり9999999999999999999、オーバーフローを与えたと思います。
クオンルム

0

muruの答えと同じ方法を使用した簡単な関数を次に示します

IsInteger()      # usage: IsInteger string
{               #  returns: flag
        [ "$1" -eq "$1" ] 2> /dev/null
}

例:

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"

出力:

'2a3' isn't an integer
'23' is an integer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.