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
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
nebogrep -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 proreadarray
builtin. - Moje špatně jsem to ' neviděl. Děkujeme @St é phaneChazelas!
grep -P -o "(?<=$NOME\t).+"