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
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
taigrep -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) nimireadarray
sisäänrakennettu. - Minun huono ' ei nähnyt sitä. Kiitos @St é phaneChazelas!
grep -P -o "(?<=$NOME\t).+"