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
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
ogrep -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) perreadarray
builtin. - Il mio cattivo ' non lha visto. Grazie @St é phaneChazelas!
grep -P -o "(?<=$NOME\t).+"