/ बिन / डैश: जांचें कि क्या $ 1 एक संख्या है


12

यह जांचने का सबसे अच्छा तरीका क्या होगा कि $ 1 / बिन / डैश में पूर्णांक है?

बाश में, मैं कर सकता था:

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

लेकिन ऐसा लगता है कि पोसिक्स अनुपालन नहीं करता है और डैश इसका समर्थन नहीं करता है

जवाबों:


12

निम्नलिखित पूर्णांकों का पता लगाते हैं, सकारात्मक या नकारात्मक, और इसके अंतर्गत काम करते dashहैं और POSIX हैं:

विकल्प 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पूर्णांक नहीं है, लेकिन यह परीक्षा उत्तीर्ण होगी।
गॉडलीजेक

3
Grep संस्करण, वह है। केस संस्करण सही दिखता है।
गॉडलीजेक

5

चाहे dash, bash, ksh, zsh, POSIX sh, या posh( "बॉर्न शैल के एक reimplementation" sh ); caseनिर्माण सबसे व्यापक रूप से उपलब्ध है और विश्वसनीय है:

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

क्या आपने इसके तहत परीक्षण किया dash? यह मेरे लिए काम करता है bashलेकिन नहीं dash
जॉन 1024

हां, मैंने अपने सिस्टम पर भी इसका परीक्षण किया dash; echo $?केस कमांड के बाद मैंने जो परिणाम जोड़ा, उससे पूछताछ करना ।
Janis

मैंने ऐसा ही किया (डेबियन स्थिर) लेकिन कोई खुशी नहीं। एक संपूर्ण उदाहरण के लिए जो मेरे डैश के तहत मेरे लिए काम करता है, मेरा विकल्प 2 देखें
जॉन 1024

हम्म, मेरे पास परीक्षण करने के लिए कोई मूल बोर्न शेल उपलब्ध नहीं है। डॉक्स जो मैंने "सुविधाओं में [ksh में] बोर्न शेल में नहीं" का निरीक्षण किया था, कम से कम इसका उल्लेख नहीं करता है, इसलिए मुझे लगता है कि यह वहां था। नहीं? - फिर अग्रणी कोष्ठक को छोड़ दें। - ओटीओएच, posh("बॉर्न शेल का एक पुन: कार्यान्वयन") को भी उस समाधान के साथ कोई समस्या नहीं है, हालांकि।
Janis

1
@mikeserv; ऐसे कई कारण हैं कि मैं हमेशा मेल खाते हुए कोष्ठक का उपयोग करता हूं case; एक कारण यह है कि आप जिस बग का वर्णन करते हैं, एक और जो संपादकों में ऐसी विशेषताएं हैं जो मेल कोष्ठक (vim) से मेल खाने पर निर्भर करती हैं यह बहुत बेहतर समर्थन देता है, और कम से कम मुझे व्यक्तिगत रूप से बेहतर लगता है कि उनका मिलान हो। - WRT poshPOSIX होने के नाते; ठीक है, मैन पेज से बोली कि मैंने कुछ और सुझाया है, लेकिन कोई भी इस तरह के अनौपचारिक बयानों पर भरोसा नहीं कर सकता है, मुझे लगता है। पुराने बोर्न शेल वैसे भी इतना महत्वपूर्ण नहीं है कि अब हम पोसिक्स युग में हैं।
Janis

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 "एक संख्या है। ध्यान दें कि यह डैश के साथ काम करता है, लेकिन अन्य सभी POSIX गोले नहीं क्योंकि व्यवहार अप्रभावित है यदि ऑपरेंड नोट किए गए पूर्णांक हैं। उदाहरण के लिए, ksh के साथ, यह कहेगा कि SHLVLया 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 वूप्स। क्या यह है $(( ... ))? यदि हां, तो मेरा जवाब अभी भी भौतिक रूप से सही होना चाहिए, मुझे बस कुछ अतिरिक्त उद्धरण जोड़ने की आवश्यकता है।
गॉडलीजेक

यह तुम्हारा उत्तर है: पता करो।
ग्लेन जैकमैन

ऐसा लगता है कि यह करता है, इसलिए मेरे अद्यतन संस्करण को चाल करना चाहिए। मेरे पास इसका परीक्षण करने के लिए डैश नहीं है, हालांकि - तो मुझे बताएं कि क्या मैंने कुछ और याद किया।
गॉडलीजेक

मैंने कोशिश की: check_if_number 1.2और समारोह लौट आया: dash: 3: arithmetic expression: expecting EOF: "1.2"
जॉन 1024

0

शायद साथ expr?

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

न तो matchहै और न ही \+POSIX हैं। यह भी कहेंगे 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 पूर्णांक नहीं है (और कहते हैं -12 वह है जो ओपी के बैश समाधान को अस्वीकार कर दिया गया होगा)। कुछ exprकार्यान्वयन कहेंगे कि 9999999999999999999 पूर्णांक नहीं है। POSIX कोई वारंटी नहीं देता है कि यह काम करेगा। व्यवहार में, कम से कम एक जीएनयू प्रणाली पर, यह कहेंगे कि "लंबाई" एक पूर्णांक है।
स्टीफन चेजलस

मेरे परीक्षण में, यह कम से कम डेबियन और OSX में काम करता है। यह कहता है कि 0. पूर्णांक के लिए पूर्णांक सुनिश्चित करें कि एक्सपायरी अंकगणित के लिए $ एक वैध अभिव्यक्ति (पूर्णांक) होना चाहिए।
cuonglm

अरे हाँ, क्षमा करें, मैंने आपके परीक्षण को $ के लिए अनदेखा कर दिया था? <2. फिर भी expr 9999999999999999999 + 0मुझे एक 3 बाहर निकलें स्थिति देता है और expr -12 + 0और expr length + 0मुझे जीएनयू expr के साथ एक 0 बाहर निकलें दर्जा देने ( + stringबलों stringजीएनयू के साथ एक स्ट्रिंग के रूप में विचार किया जाना exprexpr "$a" - 0बेहतर काम करेंगे)।
स्टीफन चेज़लस

@ स्टीफनचेज़ेलस: ओह, हां, मेरे जवाब को अपडेट किया। मुझे लगता -12है कि एक वैध पूर्णांक है, और 9999999999999999999एक अतिप्रवाह दिया।
cuonglm

0

यहाँ एक सरल विधि है जिसका उपयोग मुरु के उत्तर की तरह है :

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.