web-dev-qa-db-ja.com

配列要素がすべてbashで等しいかどうかをテストするにはどうすればよいですか?

次の配列は、各Linuxマシンのディスクの数を表しています

単一アレイにはlinux machine上のディスク数が含まれます。

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
15
yael

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

英語の説明:配列の要素を一意にソートした結果、要素が1つだけになる場合は、「ok」と出力します。それ以外の場合は「不良」を印刷します。

配列は各要素を区切るNULバイトで出力され、GNUソート(-z別名--zero-terminatedおよび-u別名--uniqueオプションに依存)にパイプされ、次にgrep(オプションを使用)にパイプされます-z別名--null-dataおよび-c別名--count)は、出力行をカウントします。

以前のバージョンとは異なり、ここではwcを使用できません。これは、改行で終了する入力行が必要であり、sedまたはtrを使用してNULを改行に変換した後でsortは、NULセパレーターを使用する目的を無効にします。 grep -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
12
cas

zshの場合:

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

ここで、(u)nique値を展開するためのパラメーター展開フラグです。したがって、配列内の一意の値の数を取得しています。

== 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

(配列をサポートするすべてのBourneのようなシェルで動作します(ksh、zsh、bash、yash))。

空の配列に対してOKを返すことに注意してください。必要がない場合は、関数の先頭に[ "$#" -gt 0 ] || returnを追加します。

8

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
RomanPerekhrest

文字列でも機能する別のbashのみのソリューションがあります。

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
4
jesse_b

BashとGNU grep:

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

ここにPOSIX Awkがあります:

awk 'BEGIN {while (++z < ARGC) if (ARGV[z] != ARGV[1]) exit 1}' "${ARRAY_DISK_Quantity[@]}"
1
Steven Penny

bashのみのソリューション(aARRAY_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
0
Bhavin Chirag

Forループを使用して、各配列要素を次の配列要素と比較します。配列の長さよりも1反復少ないループを終了して、最後の要素が最後の要素と比較されないようにします。

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