Le tableau suivant représentait le nombre de disques sur chaque machines Linux
Chacun tableau unique inclut le nombre de disques sur une machine Linux.
echo ${ARRAY_DISK_Quantity[*]}
4 4 4 4 2 4 4 4
quel est le moyen simple d'identifier que toutes les valeurs de la matrice sont égales?
Bon état:
4 4 4 4 4 4 4 4
Mauvais état:
4 4 4 4 4 4 2 4
Mauvais état:
6 6 6 6 6 6 6 6 6 6 2 6 2
bash
+ GNU sort
+ GNU grep
Solution:
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
FRANÇAIS Explication: Si le tri unique des éléments de la matrice ne donne qu'un seul élément, puis imprimez "OK". Sinon, imprimez "mauvais".
La matrice est imprimée avec des octets Nul séparant chaque élément, canalisé dans GNU Trier (s'appuyer sur le -z
alias --zero-terminated
et -u
alias --unique
options), puis en grep
(en utilisant Options -z
alias --null-data
et -c
alias --count
) Pour compter les lignes de sortie.
Contrairement à ma version précédente, je ne peux pas utiliser wc
ici car il nécessite des lignes de saisie terminées avec une nouvelle ligne ... et en utilisant sed
ou tr
pour convertir les nuls aux nouvelles lignes suivantes. Le sort
vaincrait le but d'utiliser des séparateurs nul. grep -c
fait un substitut raisonnable.
Voici la même chose réécrite comme une fonction:
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
Avec zsh
:
if ((${#${(u)ARRAY_DISK_Quantity[@]}} == 1)); then
echo OK
else
echo not OK
fi
Où (u)
est un drapeau d'expansion des paramètres pour développer nique valeurs. Nous obtenons donc un nombre de valeurs uniques dans le tableau.
Remplacer == 1
avec <= 1
Est-ce que vous voulez envisager un tableau vide est OK.
Avec ksh93
, vous pouvez trier le tableau et vérifier que le premier élément est le même que le dernier:
set -s -- "${ARRAY_DISK_Quantity[@]}"
if [ "$1" = "${@: -1}" ]; then
echo OK
else
echo not OK
fi
Avec ksh88 ou pdksh/mksh:
set -s -- "${ARRAY_DISK_Quantity[@]}"
if eval '[ "$1" = "${'"$#"'}" ]'; then
echo OK
else
echo not OK
fi
Avec bash
, vous auriez probablement besoin d'une boucle:
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
(Travaillerait avec toutes les coquilles de type Bourne avec support réseau (ksh, zsh, bash, yash)).
Notez qu'il renvoie OK pour un tableau vide. Ajouter un [ "$#" -gt 0 ] || return
Au début de la fonction si vous ne le souhaitez pas.
bash
+ awk
Soltion:
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
}
Cas de test n ° 1:
ARRAY_DISK_Quantity=(4 4 4 4 4 2 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Bad
Cas de test n ° 2:
ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
get_status "${ARRAY_DISK_Quantity[@]}"
status: Ok
J'ai une autre solution bash uniquement qui devrait également travailler avec des chaînes:
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'
}
Manifestation:
[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
Avec bash et GNU grep:
if grep -qE '^([0-9]+)( \1)*$' <<< "${ARRAY_DISK_Quantity[@]}"; then
echo "okay"
else
echo "not okay"
fi
Voici POSIX AWK:
awk 'BEGIN {while (++z < ARGC) if (ARGV[z] != ARGV[1]) exit 1}' "${ARRAY_DISK_Quantity[@]}"
bash Seul Solution (en supposant que a
est 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
Utilisez une boucle pour comparer chaque élément de tableau à l'autre. Mettre fin à la boucle une itération inférieure à la longueur de la matrice pour éviter de comparer le dernier élément à rien à la fin.
for (( i=0; i<((${#array[@]}-1)); i++ )); do
[ "${array[$i]}" != "${array[(($i+1))]}" ] && echo "Mismatch"
done
echo "Match"