Jeg skriver mit første BASH-script, jeg har nogle erfaringer med c og c #, så jeg tror logikken i programmet er korrekt..det er bare syntaksen er så kompliceret, fordi der tilsyneladende er milliarder af måder at skrive den samme ting på!
Alligevel er her scriptet: det kontrollerer simpelthen, om argumentet (streng) er indeholdt i en bestemt fil. I så fald gemmer den hver linje i filen i et array og skriver et element i arrayet i en fil. Jeg er sikker på, at der skal være lettere måder at opnå det på, men jeg vil øve mig lidt med bash loops
#!/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
Denne kode returnerer kun det andet punkt af myArray (myArray[2]
eller anden linje i filen) .. hvorfor?
Kommentarer
Svar
IFS=$"\n" a=($(cat phonebook.txt)) for i in $(seq ${#a[*]}); do [[ ${a[$i-1]} = $name ]] && echo "${a[$i]}" done
I Bash 4 kan IFS=$"\n" a=($(cat phonebook.txt))
erstattes med mapfile -t a < phonebook.txt
.
grep -A1 udskriver en linje efter kampen. -x deaktiverer regex som -F, men det matcher kun komplet l ines.
grep -x "$name" -A1 phonebook.txt | tail -n1
Kommentarer
- Du kan ønsker at validere indholdet af filen først. Op til dig.
-
-x
deaktiverer ikke regex . - Efterlader det
$(cat phonebook.txt)
ikke citeret i denne listekontekst påberåber split + glob på udvidelsen. Her vil du have split -delen, men ikke glob -delen, så den skal deaktiveres (set -o noglob
). - Det skal være
grep -xFe "$name" -A1 phonebook.txt
ellergrep -xFA1 -- "$name" phonebook.txt
eller det vinder ' t arbejde korrekt hvis$name
starter med-
eller$POSIXLY_CORRECT
er i miljøet. - I
bash
er det ' enten[[ $string = $pattern ]]
eller[[ $string = "$otherstring" ]]
. Eller IOW, du skal citere ordudvidelser på højre side af=
operatoren inden for[[...]]
hvis du ikke ' vil ikke have, at det skal tages som et mønster.
Svar
index=0 while read line; do myArray[index]="$line" done < inputfile
Nyere versioner af bash understøtter associerende arrays. Det ville gøre det lettere:
declare -A myArray while read name; do read number myArray[name]="$number" done < inputfile echo ${myArray[name]}
Kommentarer
- og hvordan vil du returnere varen i myArray [navn + 1]?
- I det indekserede eksempel havde du allerede løsningen, så jeg kopierede ikke '.
- Må jeg være forkert, men brug af et sådant rør ville ikke gøre myArray " usynlig " uden for loop ???
- @FredericYesidPe ñ aS á nchez Hverken spørgsmålet eller mit svar indeholder en pipeline, så jeg don ' t ved hvad du taler om.
- " mens læst navn; " ser mig ud som en pipeline, alligevel, jeg fandt " erklær -a array " løser problemer, jeg fik før, tak !!! +1
Svar
I et spørgsmål med titlen “ BASH læser txt-fil og lagrer i array “Jeg føler readarray
fortjener en omtale. Et eksempel på denne metode, jeg bruger til at læse testfiler i et array, ville være:
readarray -t arrayIPblacklist < /etc/postfix/IP-black-list.txt
Det foregående indlæser en fil med IP-adresser – adskilt af nye linjer – i en matrix kaldet “ arrayIPblacklist “. Ville arbejde på din telefonbogfil. readarray
blev introduceret i bash 4, så denne metode fungerer ikke på ældre værter, der kører tidligere bash-versioner.
-t
option fjerner de nye linjeafgrænsninger fra hvert element, da du oftest ikke vil have dem inkluderet.
$ 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>
Kommentarer
- Bemærk, at det accepterede svar allerede nævnt
mapfile
som er et andet (omend mere forvirrende) navn tilreadarray
indbygget. - Min dårlige- så ikke ' det ikke. Tak @St é phaneChazelas!
grep -P -o "(?<=$NOME\t).+"