次の配列は、各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;