次の配列は、各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
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
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
を追加します。
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
文字列でも機能する別の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
BashとGNU grep:
if grep -qE '^([0-9]+)( \1)*$' <<< "${ARRAY_DISK_Quantity[@]}"; then
echo "okay"
else
echo "not okay"
fi
ここにPOSIX Awkがあります:
awk 'BEGIN {while (++z < ARGC) if (ARGV[z] != ARGV[1]) exit 1}' "${ARRAY_DISK_Quantity[@]}"
bashのみのソリューション(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
Forループを使用して、各配列要素を次の配列要素と比較します。配列の長さよりも1反復少ないループを終了して、最後の要素が最後の要素と比較されないようにします。
for (( i=0; i<((${#array[@]}-1)); i++ )); do
[ "${array[$i]}" != "${array[(($i+1))]}" ] && echo "Mismatch"
done
echo "Match"