BASH legge il file txt e lo memorizza nellarray

Sto scrivendo il mio primo script BASH, ho una certa esperienza con c e c # quindi penso che la logica del è corretto..è solo la sintassi è così complicata perché apparentemente ci sono miliardi di modi per scrivere la stessa cosa!

Comunque ecco lo script: controlla semplicemente se largomento (stringa) è contenuto in un determinato file. In tal caso, memorizza ogni riga del file in un array e scrive un elemento dellarray in un file. Sono sicuro che ci devono essere modi più semplici per ottenerlo, ma voglio fare un po di pratica con i loop 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 

Questo codice restituisce lunico secondo elemento di myArray (myArray[2] o la seconda riga del file) .. perché?

Commenti

  • Che rilevanza ha il \ t? Sia il testo che il resto del codice si riferiscono solo a righe.
  • Non è una risposta diretta, quindi ' è solo un commento, ma ' lo faccio con uno a una riga grep; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic XY problema , quindi penso che il tuo commento dovrebbe essere una risposta. Dopotutto fa la cosa giusta.

Risposta

IFS=$"\n" a=($(cat phonebook.txt)) for i in $(seq ${#a[*]}); do [[ ${a[$i-1]} = $name ]] && echo "${a[$i]}" done 

In Bash 4 IFS=$"\n" a=($(cat phonebook.txt)) può essere sostituito con mapfile -t a < phonebook.txt.

grep -A1 stampa una riga dopo la corrispondenza. -x disabilita regex come -F ma corrisponde solo a complete l ines.

grep -x "$name" -A1 phonebook.txt | tail -n1 

Commenti

  • Potresti voler convalidare il prima il contenuto del file. Dipende da te.
  • -x non disabilita regex .
  • Lascia che $(cat phonebook.txt) non quotato in quel contesto di lista richiama split + glob sullespansione. Qui, vuoi la parte split , ma non la parte glob , quindi dovrebbe essere disabilitata (set -o noglob).
  • Dovrebbe essere grep -xFe "$name" -A1 phonebook.txt o grep -xFA1 -- "$name" phonebook.txt altrimenti ' non funzionerà correttamente se $name inizia con - o $POSIXLY_CORRECT nellambiente.
  • In bash, ' è [[ $string = $pattern ]] o [[ $string = "$otherstring" ]]. Oppure IOW, devi citare le espansioni di parole sul lato destro delloperatore = allinterno di [[...]] se non ' t voglio che venga preso come modello.

Risposta

index=0 while read line; do myArray[index]="$line" done < inputfile 

Le versioni più recenti di bash supportano gli array associativi. Ciò renderebbe più semplice:

declare -A myArray while read name; do read number myArray[name]="$number" done < inputfile echo ${myArray[name]} 

Commenti

  • e come restituiresti lelemento di myArray [name + 1]?
  • Nellesempio indicizzato avevi già la soluzione, quindi non lho ' copiata.
  • Posso essere sbagliato, ma lutilizzo di tale pipe non renderebbe myArray " invisibile " allesterno del ciclo ???
  • @FredericYesidPe ñ aS á nchez Né la domanda né la mia risposta contengono una pipeline, quindi non ' Non so di cosa stai parlando.
  • " while read name; " mi sembra un pipeline, comunque, ho trovato la " declare -a array " risolve i problemi che avevo prima, grazie !!! +1

Risposta

In una domanda intitolata “ BASH legge file txt e memorizza in array “I feel readarray merita una menzione. Un esempio di questo metodo che uso per leggere i file di test in un array sarebbe:

readarray -t arrayIPblacklist < /etc/postfix/IP-black-list.txt 

Quanto sopra carica un file di indirizzi IP separati da newline in un array chiamato “ arrayIPblacklist “. Funzionerebbe sul file della rubrica. readarray è stato introdotto in bash 4, quindi questo metodo non funziona su host meno recenti che eseguono versioni precedenti di bash.

-t rimuove i delimitatori di nuova riga da ogni elemento, poiché la maggior parte delle volte non li vuoi includere.

$ 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> 

Commenti

  • Tieni presente che la risposta accettata ha già menzionato mapfile che è un altro nome (anche se più confuso) per readarray builtin.
  • Il mio cattivo ' non lha visto. Grazie @St é phaneChazelas!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *