次の配列は、各Linuxマシンのディスク数を表しています
各単一アレイには、Linuxマシン上のディスクの数が含まれます。
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
次の配列は、各Linuxマシンのディスク数を表しています
各単一アレイには、Linuxマシン上のディスクの数が含まれます。
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」と出力します。それ以外の場合は、「bad」を印刷します。
アレイがソートGNUにパイプ(に依存する、各要素を分離バイトNULで印刷されている-z
別名--zero-terminated
と-u
別名--unique
オプション)、その後にgrep
オプションを使用して(-z
別名--null-data
と-c
aka--count
)出力行をカウントします。
私の以前のバージョンとは異なり、wc
改行で終了する入力行を必要とするため、ここで使用することはできません...そして、NULセパレータを使用する目的を無効にした後、sed
またはtr
を使用してNULを改行に変換しますsort
。 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
sort -u
一意の要素は返されませんが、同じ並べ替えを行う要素の各セットの1つが返されることに注意してください。たとえばARRAY_DISK_Quantity=(① ②)
、ロケールが通常これら2文字を同じようにソートすることを決定するGNUシステムでは、「OK」と表示されます。あなたはしたいと思いLC_ALL=C sort -u
バイトツーバイト一意性のために。
でzsh
:
if ((${#${(u)ARRAY_DISK_Quantity[@]}} == 1)); then
echo OK
else
echo not OK
fi
一意の値(u)
を展開するパラメーター展開フラグはどこにありますか。したがって、配列内の一意の値の数を取得しています。
置換は、空の配列がOK == 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
ますか?
typeset
はObsolete. See `help declare'.
、local
またはの代わりに使用する理由はありますかdeclare
?
typeset
は、4つのシェルすべてで機能するものです。また、80年代前半のksh のオリジナルのものです(変数スコープ型の設定と宣言に関しては、bashはほとんどksh88をコピーしましたが、名前を変更typeset
declare
しtypeset
て宣言するエイリアスを作成することにしました)。
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の唯一の解決策(と仮定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;