BASH txt fájl olvasása és tárolása a tömbben

Az első BASH szkriptet írom, van némi tapasztalatom a c és a c # szóval, ezért azt gondolom, hogy a A program helyes … csak a szintaxis olyan bonyolult, mert látszólag több milliárd módon írhatja ugyanazt!

Itt van a szkript: egyszerűen ellenőrzi, hogy az argumentum (karakterlánc) tartalmaz egy bizonyos fájl. Ha igen, akkor a fájl minden sorát egy tömbben tárolja, és a tömb egy elemét egy fájlba írja. Biztos vagyok benne, hogy ennek megvalósításához egyszerűbb módszereknek kell lennie, de szeretnék gyakorolni a bash ciklusokkal.

 #!/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 

Ez a kód adja vissza az egyetlen második elemet a myArray (myArray[2] vagy a fájl második sora) .. miért?

Megjegyzések

  • Milyen relevanciájú a \ t? A szöveg és a kód többi része is csak a sorokra utal.
  • Nem közvetlen válasz, ezért ' csak egy megjegyzést, de én ' d ezt egy egyvonalas grep-kel teszem; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic XY probléma , ezért úgy gondolom, hogy a megjegyzésének választ kell adnia. Végül is helyesen cselekszik.

Válasz

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

A Bash 4-ben IFS=$"\n" a=($(cat phonebook.txt)) helyettesíthető a következővel: mapfile -t a < phonebook.txt.

A grep -A1 egy sort nyomtat a meccs után. -x letiltja a regexet, mint a -F, de csak a teljes l-hez illeszkedik ines.

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

Megjegyzések

  • Ön érvényesítheti a először a fájl tartalmát. Rajtad múlik.
  • -x nem tiltja le a regexet .
  • Ennek elhagyása $(cat phonebook.txt) nem idézett abban a listakörnyezetben a split + globot hívja meg a kiterjesztésben. Itt a split részt akarja, a glob részt azonban nem, ezért azt ki kell kapcsolni (set -o noglob).
  • grep -xFe "$name" -A1 phonebook.txt vagy grep -xFA1 -- "$name" phonebook.txt legyen, különben ' t működnie kell rendesen, ha az $name - vagy $POSIXLY_CORRECT kezdetű a környezetben.
  • A bash mezőben ' vagy [[ $string = $pattern ]] vagy [[ $string = "$otherstring" ]]. Vagy IOW, meg kell idéznie a szó kibővítését az = operátor jobb oldalán a [[...]] operátoron belül, ha nem ' nem akarja, hogy mintának vegyék.

Válasz

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

A bash újabb verziói támogatják az asszociatív tömböket. Ez megkönnyítené:

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

Megjegyzések

  • és hogyan adná vissza a myArray elemét [név + 1]?
  • Az indexelt példában már megvan a megoldás, így nem másoltam '.
  • május tévedj, de egy ilyen cső használata nem tenné a myArray " láthatatlanná " a cikluson kívülre ???
  • @FredericYesidPe ñ aS á nchez Sem a kérdés, sem a válaszom nem tartalmaz csővezetéket, ezért nem ' nem tudom, miről beszélsz.
  • " a név olvasása közben; " úgy néz ki, mint egy pipeline, mindenesetre megtaláltam a " declare -a tömb " javításokat, amelyeket korábban kaptam, köszönöm !!! +1

Válasz

BASH txt fájl olvasása és tömbben tárolás <" kérdésben / em> “Úgy érzem, readarray említést érdemel. A tesztfájlok tömbbe olvasására használt módszerem például a következő lehet:

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

Az előzőek egy IP-címmel rendelkező fájlt töltenek be – új vonallal elválasztva – “ arrayIPblacklist ” nevű tömb. A telefonkönyv fájlján működne. A readarray -t a bash 4-ben vezették be, így ez a módszer nem fog működni a régebbi, korábbi bash verziókat futtató gazdagépeken.

A -t opció eltávolítja az új vonalak elválasztóit minden elemről, mivel legtöbbször nem akarja, hogy szerepeljenek benne.

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

Megjegyzések

  • Ne feledje, hogy az elfogadott válasz már említett mapfile, amely egy másik (bár zavaróbb) név a readarray beépített.
  • Az én rossz – nem láttam '. Köszönöm @St é phaneChazelas!

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük