कैसे परीक्षण करें यदि सरणी तत्व बैश में सभी समान हैं?


15

निम्न सरणी प्रत्येक लाइन मशीनों पर डिस्क की संख्या का प्रतिनिधित्व करती है

प्रत्येक एकल सरणी में एक लिनक्स मशीन पर डिस्क की संख्या शामिल है ।

echo ${ARRAY_DISK_Quantity[*]}
4 4 4 4 2 4 4 4

यह पहचानने का सरल तरीका क्या है कि सभी सरणी के मान समान हैं?

अच्छी स्थिति:

4 4 4 4 4 4 4 4

खराब स्थिति:

4 4 4 4 4 4 2 4

खराब स्थिति:

6 6 6 6 6 6 6 6 6 6 2 6 2

इतने सारे जवाब और कोई वोट नहीं?
jesse_b

क्या यह केवल पूर्णांक का परीक्षण करेगा या इसे तार का परीक्षण भी करना चाहिए?
jesse_b

मैं अभी सबसे अच्छे उत्तर की प्रतीक्षा कर रहा हूं और जल्द ही चिंता मत
करिएगा

मेरा मतलब बाकी सब से था। यह सवाल IMO के योग्य है।
jesse_b

एक बार जब आपको कम से कम इस स्तर की जटिलता की आवश्यकता होती है, तो वास्तविक प्रोग्रामिंग भाषा का उपयोग करना शुरू करने के लिए यह एक अच्छा समय है, जब तक कि बहुत देर न हो जाए ...
प्रदर्शित नाम

जवाबों:


11

bash+ GNU sort+ GNU grepसमाधान:

if [ "${#array[@]}" -gt 0 ] && [ $(printf "%s\000" "${array[@]}" | 
       LC_ALL=C sort -z -u |
       grep -z -c .) -eq 1 ] ; then
  echo ok
else
  echo bad
fi

अंग्रेजी व्याख्या: यदि सरणी के तत्वों को अद्वितीय-छांटना केवल एक तत्व में परिणत होता है, तो "ओके" प्रिंट करें। अन्यथा "बुरा" प्रिंट करें।

सरणी को NUL बाइट्स के साथ प्रत्येक तत्व को अलग करते हुए प्रिंट किया जाता है, जिसे GNU सॉर्ट ( -zउर्फ --zero-terminatedऔर -uउर्फ --uniqueविकल्पों पर निर्भर) में पाइप किया जाता है , और फिर grep(विकल्प -zउर्फ --null-dataऔर -cउर्फ का उपयोग करके )--count आउटपुट लाइनों को गिनने के लिए )।

अपने पिछले संस्करण के विपरीत, मैं wcयहाँ उपयोग नहीं कर सकता क्योंकि इसके लिए इनपुट लाइनों की आवश्यकता होती है जिसे एक नई रेखा के साथ समाप्त किया जाता है ... और NUL विभाजकों का उपयोग करने के उद्देश्य को हराने के बाद NUL को न्यूलाइन में परिवर्तित करना sedया उपयोग करना। एक उचित विकल्प बनाता है।trsortgrep -c


यहाँ एक समारोह के रूप में फिर से लिखा है:

function count_unique() {
  local LC_ALL=C

  if [ "$#" -eq 0 ] ; then 
    echo 0
  else
    echo "$(printf "%s\000" "$@" |
              sort --zero-terminated --unique |
              grep --null-data --count .)"
  fi
}



ARRAY_DISK_Quantity=(4 4 4 4 2 4 4 4)

if [ "$(count_unique "${ARRAY_DISK_Quantity[@]}")" -eq 1 ] ; then
  echo "ok"
else
  echo "bad"
fi

1
ध्यान दें कि sort -uअद्वितीय तत्व वापस नहीं आते हैं, लेकिन तत्वों के प्रत्येक सेट में से एक जो समान क्रमबद्ध होता है। उदाहरण के लिए, यह ARRAY_DISK_Quantity=(① ②)एक GNU सिस्टम पर "ओके" कहेगा, जहां आमतौर पर स्थान तय करते हैं कि 2 वर्ण समान होते हैं। आप LC_ALL=C sort -uबाइट-टू-बाइट विशिष्टता के लिए चाहते हैं ।
स्टीफन चेज़लस

सिर्फ एक और नोट यह भी विफल हो जाएगा अगर कोई अतिरिक्त डिस्क सीएलआई से प्रकट नहीं होती है, तो इस वाक्यविन्यास को जोड़ने की भी आवश्यकता है
येल

[[`प्रिंटफ़"% s \ n "" $ {ARRAY_DISK_Quantity [@]} | wc -l `-ईक्यू` प्रिंटफ "% s \ n" "$ {ARRAY_DISK_Quantity [@]} | grep -c "0" `]] && गूंज विफल
येल

@ स्टीफनचेज़ेलस स्थानीय मुद्दे से निपटने के लायक है, जैसा कि IFS मुद्दा है। एक खाली सूची के लिए परीक्षण, IMO, अलग से किया जाता है - एक खाली सेट में गैर-अद्वितीय तत्वों की जांच करने की कोई आवश्यकता नहीं है।
कैस

हाय कैस मैं आपके पिछले जवाब को पसंद करता हूं
येल

8

के साथ zsh:

if ((${#${(u)ARRAY_DISK_Quantity[@]}} == 1)); then
  echo OK
else
  echo not OK
fi

अद्वितीय(u) का विस्तार करने के लिए एक पैरामीटर विस्तार ध्वज कहां है मानों । इसलिए हमें सरणी में अद्वितीय मानों की गिनती मिल रही है।

के == 1साथ बदलें <= 1आप खाली सरणी ठीक है पर विचार करना चाहते हैं।

इसके साथ ksh93, आप सरणी को सॉर्ट कर सकते हैं और जांच सकते हैं कि पहला तत्व अंतिम के समान है:

set -s -- "${ARRAY_DISK_Quantity[@]}"
if [ "$1" = "${@: -1}" ]; then
  echo OK
else
  echo not OK
fi

Ksh88 या pdksh / mksh के साथ:

set -s -- "${ARRAY_DISK_Quantity[@]}"
if eval '[ "$1" = "${'"$#"'}" ]'; then
  echo OK
else
  echo not OK
fi

के साथ bash, आपको शायद एक लूप की आवश्यकता होगी:

unique_values() {
  typeset i
  for i do
    [ "$1" = "$i" ] || return 1
  done
  return 0
}
if unique_values "${ARRAY_DISK_Quantity[@]}"; then
  echo OK
else
  echo not OK
fi

(सरणी समर्थन (ksh, zsh, bash, yash) के साथ सभी बॉर्न-जैसे गोले के साथ काम करेंगे)।

ध्यान दें कि यह खाली सरणी के लिए ठीक है। [ "$#" -gt 0 ] || returnयदि आप ऐसा नहीं चाहते तो फ़ंक्शन के प्रारंभ में जोड़ें ।


ये सभी जवाब बैश का समर्थन नहीं करते?
येल

@ येल, एक बैश समाधान के लिए संपादन देखें। लेकिन आप क्यों इस्तेमाल करेंगे bash?
स्टीफन चेज़लस

बैश में, मदद पृष्ठ के लिए typesetकहते हैं Obsolete. See `help declare'.कि वहाँ एक कारण है कि आप के बजाय इसे का उपयोग कर रहे है localया declare?
वेजेंड्रिया

1
@wjandrea typesetवह है जो सभी 4 गोले में काम करता है। यह भी मूल है 80 के दशक की शुरुआत में ksh से एक था (bash ज्यादातर कॉपी किए गए ksh88 जब यह परिवर्तनशील स्कोपिंग सेटिंग और घोषणा के लिए आता है, लेकिन नाम बदलने typeset declareऔर typesetघोषित करने के लिए एक उपनाम बनाने का निर्णय लिया गया )।
स्टीफन चेजलस

4

bash+ awkसमाधान:

function get_status() {
    arr=("$@")    # get the array passed as argument
    if awk 'v && $1!=v{ exit 1 }{ v=$1 }' <(printf "%d\n" "${arr[@]}"); then 
        echo "status: Ok"
    else 
        echo "status: Bad"
    fi
}

टेस्ट केस # 1:

ARRAY_DISK_Quantity=(4 4 4 4 4 2 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Bad

टेस्ट केस # 2:

ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Ok

4

मेरे पास एक और बैश एकमात्र समाधान है जिसे स्ट्रिंग्स के साथ भी काम करना चाहिए:

isarray.equal () {
    local placeholder="$1"
    local num=0
    while (( $# )); do
        if [[ "$1" != "$placeholder" ]]; then
            num=1
            echo 'Bad' && break
        fi
        shift
    done
    [[ "$num" -ne 1 ]] && echo 'Okay'
}

प्रदर्शन:

[root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(4 4 4 4 2 4 4 4)
[root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
Bad
[root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
[root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
Okay
[root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(four four four four two four four four)
[root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
Bad
[root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(four four four four four four four four)
[root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
Okay

ध्यान दें कि डॉट्स फ़ंक्शन नामों में मान्य नहीं हैं, हालांकि बैश बहुत अनुदार है। यह फ़ंक्शन को निर्यात करने जैसे मुद्दों का कारण हो सकता है।
wjandrea 2


2

बैश और GNU grep के साथ:

if grep -qE '^([0-9]+)( \1)*$' <<< "${ARRAY_DISK_Quantity[@]}"; then 
  echo "okay"
else
  echo "not okay"
fi

हां, लेकिन (10 10 10 10) के बारे में क्या? नहीं तो काफी अच्छा।
जो

@ जो: अच्छा कैच। मैंने अपना उत्तर अपडेट कर दिया है।
सायरस


0

बैश केवल समाधान (माना aजाता है ARRAY_DISK_Quantity)

ttt=${a[0]}
res=0
for i in "${a[@]}"
do 
    let res+=$(if [ "$ttt" -ne "$i" ]; then echo 1; else echo 0; fi);  
done
if [ "$res" -eq 0 ]
then 
    echo "ok"
else
    echo "bad"
fi

काम करता है, लेकिन सिर्फ एक पर्याप्त होने पर सभी त्रुटियों को गिना जाता है:if [ "$ttt" -ne "$i" ]; then res=1; break; fi;
जो

0

प्रत्येक सरणी तत्व की तुलना अगले करने के लिए लूप के लिए करें। अंत में कुछ भी नहीं करने के लिए अंतिम तत्व की तुलना से बचने के लिए सरणी की लंबाई से कम लूप एक चलना समाप्त करें।

for (( i=0; i<((${#array[@]}-1)); i++ )); do
    [ "${array[$i]}" != "${array[(($i+1))]}" ] && echo "Mismatch"
done
echo "Match"

U & L पर आपका स्वागत है और आपके योगदान के लिए धन्यवाद! यदि कोई बेमेल पाया जाता है तो भी यह कोड "मैच" प्रिंट करेगा ... क्या यह इरादा है?
fra-san
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.