BASH lisant un fichier txt et le stockant dans un tableau

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

  • Quelle est la pertinence du \ t? Le texte et le reste du code se réfèrent uniquement à des lignes.
  • Ce n’est pas une réponse directe, donc ' n’est qu’une commenter, mais je ' d le faire avec un une une seule ligne grep; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic Problème XY , donc je pense que votre commentaire devrait être une réponse. Il fait la bonne chose après tout.

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 ou grep -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 le readarray builtin.
  • Mon mauvais ' na pas vu ça. Merci @St é phaneChazelas!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *