सवाल यदि कुछ सीमा के भीतर 2 अलग-अलग मानों की स्थिति (सीमा)


मान लें कि मेरे पास समन्वय है (एक्स, वाई), मैं दो श्रेणियां बनाना चाहता हूं: अच्छा या बुरा।

मुझे नहीं पता कि इसे शब्दों या कीवर्ड में कैसे रखा जाए, इसलिए मैंने जो कुछ भी चाहते हैं उसका एक उदाहरण बनाया।

मैंने इस तरह एक बैश स्क्रिप्ट बनाई है:

x=3.5 #(example)
y=-2.5 #(example)
if [ $x -ge 0.1 -a $x -le 5.5 ] && [ $y -ge -5.9 -a $y -le -0.1 ]; then cat="good";
elif [ $x -ge 5.5 -a $x -le 10.5 ] && [ $y -ge -10.9 -a $y -le -5.9 ]; then cat="bad";
fi
echo "$cat"

उस स्क्रिप्ट पर मैं जानना चाहता हूं कि x 0.1 से 5.5 (0.1 <x <5.5) और y के भीतर -5.9 से -0.1 (-5.9 <y <-0.1) सत्य है तो यह परिणाम देता है good। विभिन्न सीमाओं के साथ यह एक देना चाहिए bad परिणाम।

मैंने इसे चलाया है और यह परिणाम पूर्णांक अभिव्यक्ति के रूप में परिणाम देता है।

जब मैं ऑपरेटर को बदलने की कोशिश करता हूं -ge (या -leऑपरेटर के साथ) > (या <), या एक स्क्वायर ब्रैकेट जोड़ने की कोशिश करें और जो भी मैं सोच सकता हूं, यह वही त्रुटि देता है या कोई परिणाम नहीं दिया जाता है।

मुझे इस बात से कैसे संपर्क करना चाहिए?


1
2018-06-22 09:34


मूल


महज प्रयोग करें else आपकी दूसरी स्थिति के लिए, और < या > ASCII तालिका में संख्या लेकिन चरित्र स्थान की तुलना करने के लिए उपयोग नहीं किया जाता है - damadam
ऐसा इसलिए है क्योंकि बैश केवल पूर्णांक गणित कर सकता है। क्या मानों में अधिकतम एक दशमलव स्थान है? फिर आप बस उन सभी को 10 से गुणा कर सकते हैं और आपके पास पूर्णांक हैं। अगर वे मनमाने ढंग से सटीक हैं, तो आप इसका उपयोग कर सकते हैं bc। - danzel
क्योंकि अगर परिणाम क्या होगा x=3.5 तथा y=-7.9 ? - damadam
कुछ सीमा के लिए एक और 'एलिफ' होगा, मैंने इसे दो उदाहरण देने के लिए बस रखा है - maulana
यदि आप पहले से ही अपने डेटा को संसाधित कर रहे हैं awk, यह शायद जाने के लिए और अधिक समझ में आता है awk अंकगणित करो - steeldriver


जवाब:


बैश केवल पूर्णांक गणित कर सकता है। यदि मानों में दशमलव स्थानों की निश्चित संख्या है, तो आप इसे हटा सकते हैं . (का उपयोग करते हुए sed या awk या आपके द्वारा पसंद की जाने वाली कोई भी आदेश) और परिणामी मानों की तुलना करें। उदाहरण के लिए, यदि उनके पास बिल्कुल एक दशमलव स्थान है 10.0, 0.4, 2.2, हटा रहा है . दस से गुणा करेंगे, जिसके परिणामस्वरूप 100, 04, 22 (पुराने परीक्षण कमांड का उपयोग कर [, अग्रणी 0पूर्णांक तुलना के लिए कोई फर्क नहीं पड़ता)। निश्चित रूप से, आपको सीमाओं को तदनुसार गुणा करना होगा।

वैकल्पिक रूप से, आप इसका उपयोग कर सकते हैं bc, जो मनमाने ढंग से सटीक फ्लोटिंग बिंदु संख्याओं के साथ काम करेगा। bc पढ़ता stdin, इसलिए, उदाहरण के लिए, अभिव्यक्ति गूंज सकते हैं और इसे पाइप कर सकते हैं bc निम्नलिखित नुसार:

echo "$x>=0.1 && $x<=5.5" | bc

आउटपुट होगा 1 अगर अभिव्यक्ति है true, 0 अन्यथा। मैनुअल पढ़ें (आदमी बीसी) यदि आप इसके वाक्यविन्यास के बारे में अधिक जानना चाहते हैं।

इसे अपनी स्क्रिप्ट में शामिल करने के लिए, आप इस तरह कमांड प्रतिस्थापन का उपयोग कर सकते हैं:

if [ $(echo "$x>=0.1 && $x<=5.5" | bc) -eq 1 ] ; then cat="good";

ध्यान दें कि हमें अभी भी जांचना होगा कि क्या है bc कमांड का आउटपुट है 1, इसलिये [ 0 ] का मूल्यांकन भी करेगा true

अंत में, आपका उदाहरण उपयोग कर रहा है bc:

x=6.5 #(example)
y=-7.5 #(example)
if [ $(echo "$x>=0.1 && $x<=5.5 && $y>=-5.9 && $y<=-0.1" | bc) -eq 1 ] ; then cat="good";
elif [ $(echo "$x>=5.5 && $x<=10.5 && $y>=-10.9 && $y<=-5.9" | bc) -eq 1 ]; then cat="bad";
fi
echo "$cat"

चूंकि ब्रैकेट के अंदर उन मुश्किल पठनीय तारों को होने से यह अधिक त्रुटि प्रवण हो जाता है, इसलिए आप निम्न उदाहरणों जैसे बैश फ़ंक्शंस और चर का उपयोग कर सकते हैं। यदि आप अतिरिक्त जोड़ना चाहते हैं तो यह उपयोगी हो सकता है elif विभिन्न श्रेणियों के साथ खंड। (करने के लिए धन्यवाद wjandrea उपयोगी संकेतों के लिए)

x=6.5 #(example)
y=-6.5 #(example)

boundsGood="0.1 5.5 -5.9 -0.1"
boundsBad="5.5 10.5 -10.9 -5.9"

# Paramaters in following order: x, y, xmin, xmax, ymin, ymax; bounds are inclusive.
function in_bounds {
    local x=$1
    local y=$2
    local x_min=$3
    local x_max=$4
    local y_min=$5
    local y_max=$6
    [ $(echo "$x >= $x_min && $x <= $x_max && $y >= $y_min && $y <= $y_max" | bc) -eq 1 ]
}

if in_bounds $x $y $boundsGood ; then cat="good";
elif in_bounds $x $y $boundsBad ; then cat="bad";
fi
echo "$cat"

के वैकल्पिक संस्करण in_bounds का उपयोग कर काम करते हैं printf (करने के लिए धन्यवाद steeldriver):

# Paramaters in following order: x, y, xmin, xmax, ymin, ymax; bounds are inclusive.
function in_bounds {
    [ $(printf "x = %f; y = %f; xmin = %f; xmax = %f; ymin = %f; ymax = %f; x >= xmin && x <= xmax && y >= ymin && y <= ymax\n" "$1" "$2" "$3" "$4" "$5" "$6" | bc) -eq 1 ]
}

4
2018-06-22 10:41





यदि शैल स्क्रिप्ट के भीतर रहना बिल्कुल जरूरी है - तो प्रीपेड चर awk पास करने के लिए एम्बेडेड स्क्रिप्ट x तथा y अजीब के पर्यावरण और उपयोग में मूल्य ENVIRON["variable_name"] उन्हें एक्सेस करने के लिए; और इसे आपको आवश्यक तारों को मुद्रित करने का काम करने दें (या पूरी स्क्रिप्ट को लपेटें $(...) आउटपुट को बचाने के लिए)।

यदि यह आवश्यक नहीं है, तो खोल स्क्रिप्ट भाग से दूर रहें, और केवल अजीब अकेले सबकुछ संभालने दें।

#!/bin/sh

x=3.5
y=-2.5
x="$x" y="$y" awk 'BEGIN{ 
        print ENVIRON["x"],ENVIRON["y"];
        if ((ENVIRON["x"] >= 0.1) && (ENVIRON["x"] <= 5.5) \
           && (ENVIRON["y"] >= -5.9) &&  (ENVIRON["y"] <= -0.1)){
              print "good";
        }
        else if ((ENVIRON["x"] >= 5.5) && (ENVIRON["x"] <= 10.5) \
           && (ENVIRON["y"] >= -10.9) &&  (ENVIRON["y"] <= -5.9)){
             print "bad";
        }

}' # End of awk

2
2018-06-22 19:58