BASH lukee txt-tiedoston ja tallentaa taulukkoon

Kirjoitan ensimmäisen BASH-komentosarjan, minulla on jonkin verran kokemusta c: stä ja c #: sta, joten luulen, että Ohjelma on oikea..syntaksi on vain niin monimutkainen, koska ilmeisesti on miljardeja tapoja kirjoittaa sama asia!

Tässä on komentosarja: se vain tarkistaa onko argumentti (merkkijono) sisältyvät tiettyyn tiedostoon. Jos näin on, se tallentaa tiedoston kukin rivi matriisiin ja kirjoittaa taulukon osan tiedostoon. Olen varma, että siihen on oltava helpompia tapoja, mutta haluan harjoittaa jonkin verran bash-silmukoita.

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

Tämä koodi palauttaa ainoan toisen kohteen myArray (myArray[2] tai tiedoston toinen rivi) .. miksi?

Kommentit

  • Mikä merkitys \ t on? Sekä teksti että muu koodi viittaavat vain riveihin.
  • Ei suora vastaus, joten se ' on vain kommentti, mutta minä ' d teen tämän yhden linjan grepillä; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic XY-ongelma , joten mielestäni kommenttisi pitäisi olla vastaus. Se tekee kuitenkin oikean asian.

Vastaus

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

Tasossa 4 IFS=$"\n" a=($(cat phonebook.txt)) voidaan korvata nimellä mapfile -t a < phonebook.txt.

grep -A1 tulostaa yhden rivin ottelun jälkeen. -x poistaa regexin, kuten -F, mutta se vastaa vain täydellistä l ines.

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

Kommentit

  • Voit haluta vahvistaa ensin tiedoston sisältö. Sinusta päättää.
  • -x ei poista regexiä käytöstä.
  • Jos jätät $(cat phonebook.txt), jota ei ole mainittu tässä luettelokontekstissa, käyttää split + globia laajennuksessa. Tässä haluat split -osan, mutta et glob -osaa, joten se tulisi poistaa käytöstä (set -o noglob).
  • Sen pitäisi olla grep -xFe "$name" -A1 phonebook.txt tai grep -xFA1 -- "$name" phonebook.txt tai se voitti ' t oikein, jos $name alkaa - tai $POSIXLY_CORRECT on ympäristössä.
  • Kohdassa bash se ' on joko [[ $string = $pattern ]] tai [[ $string = "$otherstring" ]]. Tai IOW, sinun on lainattava sanalaajennuksia = -operaattorin oikealla puolella [[...]] -tilassa, jos et ' et halua sen ottavan mallia.

Vastaa

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

Bashin uudemmat versiot tukevat assosiatiivisia taulukoita. Se helpottaisi sitä:

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

kommentit

  • ja kuinka palautat myArray-kohteen [nimi + 1]?
  • Hakemistossa olevassa esimerkissä sinulla oli jo ratkaisu, joten en ' kopioinut sitä.
  • Saanko olla väärässä, mutta tällaisen putken käyttäminen ei tekisi myArray " näkymättömäksi " silmukan ulkopuolelle ???
  • @FredericYesidPe ñ aS á nchez Kysymys tai vastaukseni eivät sisällä putkea, joten en ' t tiedä mistä puhut.
  • " lukiessasi nimeä; " näyttää minulta putkilinja, löysin joka tapauksessa " julistaa -a-taulukon " korjaa aiemmin saamani ongelmat, kiitos !!! +1

vastaus

Kysymyksessä nimeltä ” BASH txt-tiedoston lukeminen ja tallentaminen taulukkoon ”Mielestäni readarray ansaitsee maininnan. Esimerkki tästä menetelmästä, jota käytän lukemaan testitiedostoja matriisiin, olisi:

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

Edellä mainittu lataa uuden rivillä erotetun IP-osoitteiden tiedoston taulukko nimeltä ” arrayIPblacklist ”. Toimii puhelinluettelotiedostossasi. readarray otettiin käyttöön bash 4: ssä, joten tämä menetelmä ei toimi vanhemmilla isännillä, jotka käyttävät aikaisempia bash-versioita.

-t -vaihtoehto poistaa uuden rivin erottimet jokaisesta elementistä, koska et useinkaan halua niiden sisältyvän.

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

Kommentit

  • Huomaa, että hyväksytty vastaus mainitsi jo mapfile, joka on toinen (vaikkakin sekavampi) nimi readarray sisäänrakennettu.
  • Minun huono ' ei nähnyt sitä. Kiitos @St é phaneChazelas!

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *