BASH læser txt-fil og lagrer i array

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

  • Hvilken relevans har \ t? Både teksten og resten af koden refererer bare til linjer.
  • Ikke et direkte svar, så det ' er bare et kommentar, men jeg ' d gør dette med en a one liner grep; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic XY-problem , så jeg synes, at din kommentar skal være et svar. Det gør trods alt det rigtige.

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 eller grep -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 til readarray indbygget.
  • Min dårlige- så ikke ' det ikke. Tak @St é phaneChazelas!

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *