Vyhledávání na webu

Práce s poli v Linux Shell Scripting – část 8


Nedokážeme si představit programovací jazyk bez konceptu polí. Nezáleží na tom, jak jsou implementovány mezi různými jazyky. Místo toho nám pole pomáhají při konsolidaci dat, podobných nebo odlišných, pod jedním symbolickým názvem.

Protože se zabýváme skriptováním shellu, tento článek vám pomůže pohrát si s některými skripty shellu, které využívají tento koncept polí.

Inicializace a použití pole

S novějšími verzemi bash podporuje jednorozměrná pole. Pole může být explicitně deklarováno pomocí shell-builtin declare.


declare -a var  

Ale není nutné deklarovat proměnné pole, jak je uvedeno výše. Jednotlivé prvky můžeme vkládat přímo do pole následovně.


var[XX]=<value>

kde „XX“ označuje index pole. K dereferenci prvků pole použijte syntaxi složených závorek, tj.


${var[XX]}

Poznámka: Indexování pole vždy začíná 0.

Dalším pohodlným způsobem inicializace celého pole je použití dvojice závorek, jak je uvedeno níže.


var=( element1 element2 element3 . . . elementN )

Existuje ještě další způsob přiřazování hodnot do polí. Tento způsob inicializace je podkategorií výše popsané metody.


array=( [XX]=<value> [XX]=<value> . . . )

Můžeme také číst/přiřazovat hodnoty do pole během doby provádění pomocí shell-builtin read.


read -a array

Nyní po provedení výše uvedeného příkazu uvnitř skriptu čeká na nějaký vstup. Potřebujeme poskytnout prvky pole oddělené mezerou (a ne návrat vozíku). Po zadání hodnot stiskněte enter pro ukončení.

K procházení prvky pole můžeme také použít for loop.


for i in “${array[@]}”
do
	#access each element as $i. . .
done 

Následující skript shrnuje obsah této konkrétní části.


#!/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ůzné operace na polích

Mnoho standardních operací s řetězci funguje na polích. Podívejte se na následující ukázkový skript, který implementuje některé operace s poli (včetně operací s řetězci).


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

Následuje výstup vytvořený při provádění výše uvedeného skriptu.


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

Myslím, že nemá žádný význam podrobně vysvětlovat výše uvedený skript, protože je samovysvětlující. V případě potřeby věnuji jeden díl této série výhradně manipulaci se strunami.

Náhrada příkazů pomocí polí

Náhrada příkazů přiřadí výstup příkazu nebo více příkazů do jiného kontextu. Zde v tomto kontextu polí můžeme vložit výstup příkazů jako jednotlivé prvky polí. Syntaxe je následující.


array=( $(command) )

Ve výchozím nastavení je obsah ve výstupu příkazu oddělený mezerami zasunut do pole jako jednotlivé prvky. Následující skript uvádí obsah adresáře, což jsou soubory s oprávněními 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

Simulace dvourozměrných polí

Můžeme snadno reprezentovat 2-rozměrnou matici pomocí 1-rozměrného pole. V řádkovém hlavním pořadí jsou prvky reprezentace v každém řádku matice postupně ukládány do indexů pole sekvenčním způsobem. Pro matici mXn lze vzorec pro totéž zapsat jako.


matrix[i][j]=array[n*i+j]

Podívejte se na další ukázkový skript pro přidání 2 matic a tisk výsledné matice.


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

I když existují omezení pro implementaci polí uvnitř skriptování shellu, stává se užitečným v několika situacích, zvláště když řešíme substituci příkazů. Podíváme-li se z administrativního hlediska, koncept polí vydláždil cestu pro vývoj mnoha skriptů na pozadí v systémech GNU/Linux.