Jécris mon premier script BASH, jai une certaine expérience avec c et c # donc je pense que la logique du le programme est correct..il est juste la syntaxe est si compliquée car apparemment il y a des milliards de façons décrire la même chose!
Quoi quil en soit voici le script: il vérifie simplement si largument contenu dans un certain fichier. Si tel est le cas, il stocke chaque ligne du fichier dans un tableau et écrit un élément du tableau dans un fichier. Je suis sûr quil doit y avoir des moyens plus simples pour y parvenir, mais je veux faire un peu de pratique avec les boucles bash
#!/bin/bash NOME=$1 c=0 #IF NAME IS FOUND IN THE PHONEBOOK THANK STORE EACH LINE OF THE FILE INTO ARRAY #ONCE THE ARRAY IS DONE GET THE INDEX OF MATCHING NAME AND RETURN ARRAY[INDEX+1] if grep "$NOME" /root/phonebook.txt ; then echo "CREATING ARRAY" while read line do myArray[$c]=$line # store line c=$(expr $c + 1) # increase counter by 1 done < /root/phonebook.txt else echo "Name not found" fi c=0 for i in myArray; do if myArray[$i]="$NOME" ; then echo ${myArray[i+1]} >> /root/numbertocall.txt fi done
Ce code ne renvoie que le deuxième élément de myArray (myArray[2]
ou la deuxième ligne du fichier) .. pourquoi?
Commentaires
Réponse
IFS=$"\n" a=($(cat phonebook.txt)) for i in $(seq ${#a[*]}); do [[ ${a[$i-1]} = $name ]] && echo "${a[$i]}" done
Dans Bash 4 IFS=$"\n" a=($(cat phonebook.txt))
peut être remplacé par mapfile -t a < phonebook.txt
.
grep -A1 affiche une ligne après la correspondance. -x désactive lexpression régulière comme -F mais il ne correspond quà l complet ines.
grep -x "$name" -A1 phonebook.txt | tail -n1
Commentaires
- Vous pouvez vouloir valider le contenu du fichier en premier. Cest à vous de décider.
-
-x
ne désactive pas lexpression régulière . - Laisser cela
$(cat phonebook.txt)
sans guillemets dans ce contexte de liste appelle split + glob sur lexpansion. Ici, vous voulez la partie split , mais pas la partie glob , elle doit donc être désactivée (set -o noglob
). - Cela devrait être
grep -xFe "$name" -A1 phonebook.txt
ougrep -xFA1 -- "$name" phonebook.txt
ou cela na pas fonctionné ' correctement si$name
commence par-
ou$POSIXLY_CORRECT
est dans lenvironnement. - Dans
bash
, ' est soit[[ $string = $pattern ]]
, soit[[ $string = "$otherstring" ]]
. Ou IOW, vous devez citer les extensions de mots sur le côté droit de lopérateur=
à lintérieur de[[...]]
si vous navez pas ' Je ne veux pas quil soit pris comme modèle.
Réponse
index=0 while read line; do myArray[index]="$line" done < inputfile
Les nouvelles versions de bash prennent en charge les tableaux associatifs. Cela faciliterait les choses:
declare -A myArray while read name; do read number myArray[name]="$number" done < inputfile echo ${myArray[name]}
Commentaires
- et comment retourneriez-vous lélément de myArray [name + 1]?
- Dans lexemple indexé, vous aviez déjà la solution, donc je nai ' pas la copier.
- Puis-je être faux, mais utiliser un tel tube ne rendrait pas myArray " invisible " en dehors de la boucle ???
- @FredericYesidPe ñ aS á nchez Ni la question ni ma réponse ne contiennent de pipeline donc je ne ' je ne sais pas de quoi vous parlez.
- " while read name; " me ressemble pipeline, de toute façon, jai trouvé le " declare -a array " corrige les problèmes que jai eu avant, merci !!! +1
Réponse
Dans une question intitulée « BASH lecture dun fichier txt et stockage dans un tableau « Je pense que readarray
mérite une mention. Un exemple de cette méthode que jutilise pour lire les fichiers de test dans un tableau serait:
readarray -t arrayIPblacklist < /etc/postfix/IP-black-list.txt
Ce qui précède charge un fichier dadresses IP – séparées par des nouvelles lignes – dans un tableau appelé « arrayIPblacklist « . Travaillerait sur votre fichier de répertoire. readarray
a été introduit dans bash 4, donc cette méthode ne fonctionnera pas sur des hôtes plus anciens exécutant des versions de bash antérieures.
Le -t
supprime les délimiteurs de nouvelle ligne de chaque élément, car la plupart du temps vous ne voulez pas quils soient inclus.
$ seq 3 | bash -c "readarray a; printf "<%q>\n" "${a[@]}"" <$"1\n"> <$"2\n"> <$"3\n"> $ seq 3 | bash -c "readarray -t a; printf "<%q>\n" "${a[@]}"" <1> <2> <3>
Commentaires
- Notez que la réponse acceptée mentionnait déjà
mapfile
qui est un autre nom (quoique plus déroutant) pour lereadarray
builtin. - Mon mauvais ' na pas vu ça. Merci @St é phaneChazelas!
grep -P -o "(?<=$NOME\t).+"