BASH čte soubor txt a ukládá do pole

Píšu svůj první skript BASH, mám nějaké zkušenosti s c a c #, takže si myslím, že logika program je správný..jen syntaxe je tak komplikovaná, protože zjevně existují miliardy způsobů, jak napsat stejnou věc!

Tady je skript: jednoduše zkontroluje, zda je argument (řetězec) obsažené v určitém souboru. Pokud ano, uloží každý řádek souboru do pole a zapíše položku pole do souboru. Jsem si jist, že musí existovat jednodušší způsoby, jak toho dosáhnout, ale chci udělat nějakou praxi s bash smyčkami

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

Tento kód vrátí pouze druhou položku z myArray (myArray[2] nebo druhý řádek souboru) .. proč?

Komentáře

  • Jaký význam má \ t? Text i zbytek kódu odkazují pouze na řádky.
  • Není to přímá odpověď, takže ' je pouze komentovat, ale ' d to udělat s jedním liner grep; grep -P -o "(?<=$NOME\t).+"
  • @Patrick Classic Problém XY , takže si myslím, že váš komentář by měl být odpovědí. Nakonec dělá správnou věc.

Odpověď

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

V Bash 4 IFS=$"\n" a=($(cat phonebook.txt)) lze nahradit mapfile -t a < phonebook.txt.

grep -A1 po zápase vytiskne jeden řádek. -x zakáže regulární výraz jako -F, ale odpovídá pouze úplnému l ines.

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

Komentáře

  • Můžete možná chtít ověřit nejprve obsah souboru. Na vás.
  • -x nezakáže regex .
  • Opuštění $(cat phonebook.txt) neuvedené v tomto seznamu vyvolá v expanzi split + glob. Zde chcete část rozdělit , ale ne část glob , takže by měla být deaktivována (set -o noglob).
  • Mělo by to být grep -xFe "$name" -A1 phonebook.txt nebo grep -xFA1 -- "$name" phonebook.txt nebo by to nemělo fungovat ' správně, pokud $name začíná na - nebo $POSIXLY_CORRECT v prostředí.
  • V bash je ' buď [[ $string = $pattern ]] nebo [[ $string = "$otherstring" ]]. Nebo IOW, musíte uvést rozšíření slov na pravé straně operátoru = uvnitř [[...]], pokud ' nechci, aby to bylo bráno jako vzor.

odpověď

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

Novější verze bash podporují asociativní pole. To by usnadnilo:

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

Komentáře

  • a jak byste vrátili položku myArray [name + 1]?
  • V indexovaném příkladu jste již řešení měli, takže jsem ho ' nekopíroval.
  • Mohu mýlit se, ale použití takové trubky by myArray " neviditelné " mimo smyčku ???
  • @FredericYesidPe ñ aS á nchez Ani otázka, ani moje odpověď neobsahuje potrubí, takže ' nevím, o čem to mluvíš.
  • " při čtení názvu; " na mě vypadá jako potrubí, každopádně jsem našel " deklarovat -a pole " opravuje problémy, které jsem dříve dostal, díky !!! +1

Odpověď

V otázce s názvem „ BASH čtení souboru txt a ukládání do pole „Cítím, readarray si zaslouží zmínku. Příkladem této metody, kterou používám ke čtení testovacích souborů do pole, by bylo:

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

Výše uvedené načte soubor IP adres – oddělených novými řádky – do pole s názvem „ arrayIPblacklist “. Fungovalo by to na vašem telefonním seznamu. readarray byl představen v bash 4, takže tato metoda nebude fungovat na starších hostitelích se staršími verzemi bash.

-t Možnost oddělí oddělovače nového řádku od každého prvku, protože je většinou nechcete mít.

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

Komentáře

  • Upozorňujeme, že přijatá odpověď již zmínila mapfile, což je jiný (i když matoucí) název pro readarray builtin.
  • Moje špatně jsem to ' neviděl. Děkujeme @St é phaneChazelas!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *