![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Le langage bash propose l‘utilisation de tableaux (array). Cela permet un traitement itératif. Bien souvent, lorsqu'on script en bash on oublie cette fonctionnalité. Petit rappel.
$ Array=(item1 item2 item3 "liste d'items")
$ echo ${Array[0]} item1 $ echo ${Array[2]} item3 i=3 $ echo ${Array[$i]} liste d'items
Le premier élément du tableau a pour index 0.
echo ${#Array[@]} 4
$ echo ${Array[*]} item1 item2 item3 liste d'items
for i in ${Array[*]} do echo $i done item1 item2 item3 liste d'items
Cette manière de faire ne donne pas forcément le résultat escompté. L'indice 4 qui contient un blanc n'est pas restitué comme on pourrait le penser.
C'est avec la manière globale la plus sur façon de faire.
$ for (( i=0; i<${#Array[@]}; i++ )); do echo "n° $i : ${Array[$i]}" done n° 0 : item1 n° 1 : item2 n° 2 : item3 n° 3 : liste d'items
Bash a une variable interne $IFS, comme awk qui détermine la césure des mots.
Il faut faire attention à son contenu. Cela peut avoir une influence sur la gestion des noms d‘éléments dans une array.
Ne pas hésiter à regarder et àchanger sa valeur.
IFS='' correspond au blanc comme séparateur.
Par exemple, si on veut utiliser la virgule comme séparateur:
$ IFS=',' arr_nombres=(12,34,56) $ echo ${arr_nombres[*]} 12 34 56 $ IFS=''
$ Array+=(item5) jlb@mignon:~$ echo ${Array[*]} item1 item2 item3 liste d'items item5
$ unset Array $ echo ${Array[*]}
La ligne blanche confirme que le tableau a été supprimé.
C'est la solution à laquelle on pense en premier. On parcourt le tableau et on teste chaque élément du tableau pour voir si il correspond à la valeur.
Il vaut mieux écrire un script. Par exemple in array.bash.
#!/bin/bash function array_contains() { local n=$# local value=${!n} for ((i=1;i < $#;i++)) { if [ "${!i}" == "${value}" ]; then echo "true" return 0 fi } echo "false" return 1 } lang=(awk c html makefile perltk python tk bash dialog js perl php tcl tkinter) for j in "awk" "ada" "python" "lisp" do if [ $(array_contains "${lang[@]}" "$j") == "true" ]; then echo $j fi done
$ ./array.bash awk python
Cela fonctionne mais ce n'est pas la solution la plus optimsée.
La solution élégante consiste à utiliser l'opérateur *=~ dans le tableau.
La syntaxe est de typr
if [[ " ${lang[@]} " =~ " ${j} " ]];
$ lang=(awk c html makefile perltk python tk bash dialog js perl php tcl tkinter) for j in ada python lisp modula bash c c++ do if [[ " ${lang[@]} " =~ " $j " ]]; then echo $j fi done python bash c
a1=(chien chat canari) $ a2=(lapin hamster souris) $ a=("${a1[@]}" "${a2[@]}") $ for i in "${a[@]}" ; do echo "$i" ; done chien chat canari lapin hamster souris
Pour un tri numérique on utilise sort -n pour les nombres et sort pour les chaines.
$ nombres=(5 23 1 12 12) $ trie=($(printf "%s\n" ${nombres[*]} | sort -n) $ echo ${trie[*]} 1 5 12 12 23
Les autres options sont possibles comme -rn pour reverse numérique, -r pour reverse, -h pour une vision "humaine" des tailles de disques et de fichiers, -u pour unique, -V pour trier par version.
Vous pouvez consulter le man de sort pour plus de possibilité.
$ nombres=(5 23 1 12 12) $ trie=($(printf "%s\n" ${nombres[*]} | sort -r) $ echo ${trie[*]} 23 12 12 5 1 sorted=($(printf "%s\n" ${nums[*]} | sort -r)) $ echo ${sorted[*]} 5 23 12 12 1 $ disk_size=($(df | awk '{print $4}' | sort -h)) $ echo ${disk_size[*]} Taille 5,0M 784M 785M 3,8G 3,9G 6,2G 8,1G 186G
On voit très dans l'exemple avec sort - que l'ordre correspond à l'ordre alphabetique et non l'ordre numérique.
On peut ausi utiliser IFS comme délimiteur.
$ rray=(item val list string) $ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS $ printf "[%s]\n" "${sorted[@]}"
Voici un exemple de script avec le très connu buble sort en utilisant une variable globale BSORT, bubble.bash .
declare BSORT=() function bubble_sort() { # # @param [ARGUMENTS]... # # Sort all positional arguments and store them in global array BSORT. # Without arguments sort this array. Return the number of iterations made. # # Bubble sorting lets the heaviest element sink to the bottom. # (($# > 0)) && BSORT=("$@") local j=0 ubound=$((${#BSORT[*]} - 1)) while ((ubound > 0)) do local i=0 while ((i < ubound)) do if [ "${BSORT[$i]}" \> "${BSORT[$((i + 1))]}" ] then local t="${BSORT[$i]}" BSORT[$i]="${BSORT[$((i + 1))]}" BSORT[$((i + 1))]="$t" fi ((++i)) done ((++j)) ((--ubound)) done } bubble_sort chat chien canari lapin souris echo ${BSORT[@]}
/bubble.bash canari chat chien lapin souris