Praca z tablicami w skryptach powłoki systemu Linux — część 8
Nie możemy sobie wyobrazić języka programowania bez koncepcji tablic. Nie ma znaczenia, jak są one zaimplementowane w różnych językach. Zamiast tego tablice pomagają nam w konsolidacji danych, podobnych lub różnych, pod jedną symboliczną nazwą.
Ponieważ zajmujemy się skryptami powłoki, ten artykuł pomoże ci w zabawie z niektórymi skryptami powłoki, które wykorzystują tę koncepcję tablic.
Inicjalizacja i użycie tablicy
W nowszych wersjach basha obsługuje tablice jednowymiarowe. Tablicę można jawnie zadeklarować za pomocą wbudowanej powłoki declare.
declare -a var
Ale nie jest konieczne deklarowanie zmiennych tablicowych jak powyżej. Poszczególne elementy możemy wstawiać bezpośrednio do tablicy w następujący sposób.
var[XX]=<value>
gdzie „XX” oznacza indeks tablicy. Aby wyłuskać elementy tablicy, użyj składni nawiasów klamrowych, tj.
${var[XX]}
Uwaga: indeksowanie tablicy zawsze zaczyna się od 0.
Innym wygodnym sposobem inicjowania całej tablicy jest użycie pary nawiasów, jak pokazano poniżej.
var=( element1 element2 element3 . . . elementN )
Istnieje jeszcze inny sposób przypisywania wartości do tablic. Ten sposób inicjalizacji jest podkategorią wcześniej wyjaśnionej metody.
array=( [XX]=<value> [XX]=<value> . . . )
Możemy także czytać/przypisywać wartości do tablicy w czasie wykonywania, korzystając z wbudowanej powłoki read.
read -a array
Teraz, po wykonaniu powyższej instrukcji w skrypcie, czeka na pewne dane wejściowe. Musimy podać elementy tablicy oddzielone spacją (a nie powrotem karetki). Po wprowadzeniu wartości naciśnij klawisz Enter, aby zakończyć.
Do poruszania się po elementach tablicy możemy także użyć pętli for.
for i in “${array[@]}”
do
#access each element as $i. . .
done
Poniższy skrypt podsumowuje zawartość tej konkretnej sekcji.
#!/bin/bash
array1[0]=one
array1[1]=1
echo ${array1[0]}
echo ${array1[1]}
array2=( one two three )
echo ${array2[0]}
echo ${array2[2]}
array3=( [9]=nine [11]=11 )
echo ${array3[9]}
echo ${array3[11]}
read -a array4
for i in "${array4[@]}"
do
echo $i
done
exit 0
Różne operacje na tablicach
Wiele standardowych operacji na ciągach działa na tablicach. Przyjrzyj się poniższemu przykładowemu skryptowi, który implementuje niektóre operacje na tablicach (w tym operacje na ciągach znaków).
#!/bin/bash
array=( apple bat cat dog elephant frog )
#print first element
echo ${array[0]}
echo ${array:0}
#display all elements
echo ${array[@]}
echo ${array[@]:0}
#display all elements except first one
echo ${array[@]:1}
#display elements in a range
echo ${array[@]:1:4}
#length of first element
echo ${#array[0]}
echo ${#array}
#number of elements
echo ${#array[*]}
echo ${#array[@]}
#replacing substring
echo ${array[@]//a/A}
exit 0
Poniżej znajdują się dane wyjściowe powstałe po wykonaniu powyższego skryptu.
apple
apple
apple bat cat dog elephant frog
apple bat cat dog elephant frog
bat cat dog elephant frog
bat cat dog elephant
5
5
6
6
Apple bAt cAt dog elephAnt frog
Myślę, że szczegółowe wyjaśnianie powyższego skryptu nie ma sensu, ponieważ jest on oczywisty. Jeśli zajdzie taka potrzeba, jedną część z tej serii poświęcę wyłącznie manipulacji strunami.
Podstawianie poleceń za pomocą tablic
Podstawianie poleceń przypisuje dane wyjściowe polecenia lub wielu poleceń do innego kontekstu. Tutaj, w kontekście tablic, możemy wstawić dane wyjściowe poleceń jako pojedyncze elementy tablic. Składnia jest następująca.
array=( $(command) )
Domyślnie zawartość wyniku polecenia oddzielona białymi znakami jest podłączana do tablicy jako pojedyncze elementy. Poniższy skrypt wyświetla zawartość katalogu, w którym znajdują się pliki z uprawnieniami 755.
#!/bin/bash
ERR=27
EXT=0
if [ $# -ne 1 ]; then
echo "Usage: $0 <path>"
exit $ERR
fi
if [ ! -d $1 ]; then
echo "Directory $1 doesn't exists"
exit $ERR
fi
temp=( $(find $1 -maxdepth 1 -type f) )
for i in "${temp[@]}"
do
perm=$(ls -l $i)
if [ `expr ${perm:0:10} : "-rwxr-xr-x"` -eq 10 ]; then
echo ${i##*/}
fi
done
exit $EXT
Symulacja tablic dwuwymiarowych
Możemy łatwo przedstawić dwuwymiarową macierz za pomocą jednowymiarowej tablicy. W głównym porządku wierszy elementy reprezentacji w każdym wierszu macierzy są stopniowo zapisywane w indeksach tablicy w sposób sekwencyjny. W przypadku macierzy mXn wzór na nią można zapisać jako.
matrix[i][j]=array[n*i+j]
Spójrz na inny przykładowy skrypt dodawania 2 macierzy i drukowania wynikowej macierzy.
#!/bin/bash
read -p "Enter the matrix order [mxn] : " t
m=${t:0:1}
n=${t:2:1}
echo "Enter the elements for first matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read x[$(($n*$i+$j))]
done
done
echo "Enter the elements for second matrix"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
read y[$(($n*$i+$j))]
z[$(($n*$i+$j))]=$((${x[$(($n*$i+$j))]}+${y[$(($n*$i+$j))]}))
done
done
echo "Matrix after addition is"
for i in `seq 0 $(($m-1))`
do
for j in `seq 0 $(($n-1))`
do
echo -ne "${z[$(($n*$i+$j))]}\t"
done
echo -e "\n"
done
exit 0
Mimo że istnieją ograniczenia w implementowaniu tablic w skryptach powłoki, staje się to przydatne w kilku sytuacjach, szczególnie gdy mamy do czynienia z podstawieniem poleceń. Patrząc z administracyjnego punktu widzenia, koncepcja tablic utorowała drogę do rozwoju wielu skryptów działających w tle w systemach GNU/Linux.