Managing and Using Arrays in Shell Scripts (page 2)

botond published 2019. 03. 11., h - 17:09 time

2. page content

 

Continuation

The description on the first page we looked at how to create indexed arrays and how to write data to or read from it. On this page, we continue to get acquainted with indexed arrays by using arrays in branches and functions.

 

 

Indexed arrays

Using arrays in junctions

There are many ways to use arrays in junctions.

Logical examination

The logical examination checks for the presence of an element of the array with a given index, which happens as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
 
tomb=(
    [0]="első elem"
    [1]="Második elem"
    [2]="Harmadik elem"
    [3]=3
    [4]=negyedik
)
 
 
# Rövid vizsgálat:
[ ${tomb[3]} ] && echo "létezik" || echo "nincs ilyen indexű elem"
# Rövid vizsgálat fordított logikával:
[ ! ${tomb[3]} ] && echo "nincs ilyen indexű elem" || echo "létezik"
 
echo
 
# Több soros vizsgálat:
if [ ${tomb[3]} ]; then
    echo "létezik"
    # További kódsorok, ha létezik az elem
else
    echo "nincs ilyen indexű elem"
    # További kódsorok, ha nem létezik az elem
fi

Here are three examples of the study. The first two are the single-line test, where we simply print out the appropriate result, and then a multi-line version, where we can place additional lines of code in the branches.

The logical reversal is a ! can also be used in the multi-line version if, for example, we only need the false branch during verification. At that time it is else without a section, you can make a shorter code.

Value testing

When examining a value, we compare the value of a given element of the array with something:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
 
tomb=(
    [0]="első elem"
    [1]="Második elem"
    [2]="Harmadik elem"
    [3]=3
    [4]=negyedik
)
 
echo -------------------------------
echo Karakter alapú vizsgálatok:
echo -------------------------------
 
echo "Rövid vizsgálatok:"
 
# Rövid vizsgálatok többféleképpen:
[ ${tomb[3]} = 3 ] && echo "megfelelő érték" || echo "nem megfelelő érték"
[ "${tomb[3]}" = 3 ] && echo "megfelelő érték" || echo "nem megfelelő érték"
[ "${tomb[0]}" = "első elem" ] && echo "megfelelő érték" || echo "nem megfelelő érték"
 
# Rövid vizsgálatok fordított logikával:
[ ! ${tomb[3]} = 3 ] && echo "nem megfelelő érték" || echo "megfelelő érték"
[ ! "${tomb[3]}" = 3 ] && echo "nem megfelelő érték" || echo "megfelelő érték"
[ ! "${tomb[0]}" = "első elem" ] && echo "nem megfelelő érték" || echo "megfelelő érték"
 
# Becsapós vizsgálat
echo "Becsapós..."
# Ennek a kiértékelése hamis lesz, mivel karakterláncként hasonlítja össze a két oldalt.
[[ 3 < 11 ]] && echo "igaz" || echo "hamis (becsapós példa)"
# Ez alapján az alábbi tömb elem összehasonlítás is hamis lesz:
[[ ${tomb[3]} < 11 ]] && echo "igaz" || echo "hamis (becsapós példa)"
 
 
# Több soros vizsgálat:
echo "Több soros vizsgálat:"
if [ "${tomb[4]}" = "negyedik" ]; then
    echo "megfelelő érték"
    # További kódsorok, ha megfelelő az érték
else
    echo "nem megfelelő érték"
    # További kódsorok, ha nem megfelelő az érték
fi
 
echo
echo -------------------------------
echo Numerikus vizsgálatok:
echo -------------------------------
 
# Rövid használat:
echo "Rövid használat:"
(( ${tomb[3]} == 3 )) && echo "Igaz feltétel" || echo "Hamis feltétel"
(( ${tomb[3]} > 1 )) && echo "Igaz feltétel" || echo "Hamis feltétel"
 
# Ez a fenti becsapós vizsgálat helyesen használt numerikus változata, itt már igaz lesz a kiértékelés:
(( 3 < 11 )) && echo "igaz (helyesen használt példa)" || echo "hamis"
# Ennek megfelelően a tömbbel végzett összehasonlítás is igaz lesz:
(( ${tomb[3]} < 11 )) && echo "igaz (helyesen használt példa)" || echo "hamis"
 
 
 
# Több soros:
echo "Több soros:"
if (( ${tomb[3]} < 11 )); then
    echo "Igaz feltétel"
    # elágazás további sorai...
else
    echo "Hamis feltétel"
    # elágazás további sorai...
fi

Here, too, we see examples of value checks. And it can be varied in many ways. (You can copy and run the example program one-by-one in the shell)

In character-based tests, it is easy to slip into error, as figures can be compared according to the deceptive example above. However, he still compares the two pages as strings, which in many cases gives a mathematically incorrect result, which is still correct for the strings.
I only added this for the sake of clarity, that when performing tests with arrays (or any other variables), make sure to compare the types of values ​​contained in them properly.

Using Arrays in Functions

You can also pass one or more arrays to functions as parameters, which you can then use in the function.

Manage parameters as an array

There are cases when it is necessary to collect all the parameters of a function into a single array. These can include custom values ​​or even arrays that contain additional value fields. The following example illustrates how this is done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
 
# Indexelt tömb feltöltése néhány számértékkel:
tomb=(100 200 500 1000 150 350 220)
 
function fuggveny {
    tomb2=("$@")                    # Összes paraméter begyűjtése egy másik tömbbe
 
    for i in "${!tomb2[@]}"; do
        ertek=${tomb2[$i]}
        printf "%3s%12s\n" "$i:" $ertek
    done
}
 
# Függvény hívása a vegyes tömb és számérték paraméterekkel
fuggveny 1 2 3 "${tomb[@]}" 4 5 6

The output of the sample program is:

 0:           1
 1:           2
 2:           3
 3:         100
 4:         200
 5:         500
 6:        1000
 7:         150
 8:         350
 9:         220
10:           4
11:           5
12:           6

It can be seen here that all the mixed parameters are included in the array used in the function.

The solution is based on calling the function between the given parameters when calling the function "$ {Array [@]}" we give it in the form, which expands all the elements of the array in the way we know before (also working with multi-word elements), that is, as if we had given them to the function one by one. Then in the function a $@ parameters are loaded into an array.

This method can come in handy, for example, when a function needs to be built without knowing the number of parameters obtained in advance, but we need to be able to process them.

For the sake of practice, in the following example program, the function also collects its numerical parameters into an array and then calculates their sum, average, and determines their minimum and maximum values:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
 
# Indexelt tömb feltöltése néhány számértékkel:
tomb=(100 200 500 1000 150 350 220)
 
# Összeget, átlagot és szélső értékekeket kiszámító függvény:
function ertekek {
    tomb2=("$@")                # Kimásoljuk egy másik változóba a teljes paramétersort
 
    # Változók kezdőértékei
    osszeg=0                    # Ebben lesz az összeg
    atlag=0                     # Ebben lesz az átlag
    minimum=${tomb2[0]}         # Legkisebb elem
    maximum=${tomb2[0]}         # Legnagyobb elem
 
    echo "Tömb elemek:"
    echo "--------------"
    for i in "${!tomb2[@]}"; do
        ertek=${tomb2[$i]}      # Változónév rövidítés, hogy áttekinthetőbb legyen
        printf "%3s%12s\n" "$i:" $ertek
 
        (( ertek > maximum )) && maximum=$ertek
        (( ertek < minimum )) && minimum=$ertek
        (( osszeg = osszeg + $ertek ))
 
    done
    # Átlag kiszámítása:
    #(( atlag = osszeg / ${#tomb[@]} ))
    # A Bash alapból csak egész számokkal dolgozik, így az előző osztás nem lenne pontos
    # Helyette a bc-vel számítjuk ki 2 tizedes pontossággal, amit egy subshell-ből olvasunk ki:
    atlag=$(echo "scale=2; $osszeg / ${#tomb2[@]}" | bc)
 
    echo "---------------"
    printf "%-10s%6s\n" "Összeg:" $osszeg
    printf "%-10s%6s\n" "Átlag:" $atlag
    printf "%-9s%6s\n" "Minimum:" $minimum
    printf "%-9s%6s\n" "Maximum:" $maximum
    echo "---------------"
}
 
# Függgvény hívása
ertekek "${tomb[@]}" 1 2 3

The output of this is:

Tömb elemek:
--------------
 0:         100
 1:         200
 2:         500
 3:        1000
 4:         150
 5:         350
 6:         220
 7:           1
 8:           2
 9:           3
---------------
Összeg:    2526
Átlag:   252.60
Minimum:      1
Maximum:   1000
---------------

Here, too, we can observe that whether we assign individual numeric values ​​to the function or an array, as well as the order of their choice, the function processes all the numeric values ​​obtained.

With this solution we can dynamically manage the obtained parameters, no matter their quantity, but there are also limitations: we cannot handle the array parameters separately, so we can only use them for common tasks in the function. Therefore, a solution may be needed where the resulting array parameters are processed separately.

 

 

Manage multiple array parameters separately

It is also possible within the function to handle the resulting array parameters separately, thus providing other options, configuration commands, etc., in addition to the data parameters given to the function. The following example shows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
 
# 1. indexelt tömb feltöltése néhány adattal:
tomb1=(100 200 500 "több szavas" "másik három szavas")
 
# 2. indexelt tömb feltöltése néhány számértékkel:
tomb2=("másik tömb" 2000 "ebben is vannak több szavas elemek" 2500 3000 "a-b c")
 
 
function fuggveny {
    # param1 és param2 nevű tömbök deklarálása a paraméterekben kapott NEVEK alapján
    declare -n param1=$1
    declare -n param2=$2
 
    echo "-----------------------------"
    echo "1. Paramétertömb kilistázása:"
    echo "-----------------------------"
    for i in "${!param1[@]}"; do
        ertek=${param1[$i]}
        echo "$i: $ertek"
    done
 
    echo
    echo "-----------------------------"
    echo "2. Paramétertömb kilistázása:"
    echo "-----------------------------"
    for i in "${!param2[@]}"; do
        ertek=${param2[$i]}
        echo "$i: $ertek"
    done
 
    echo
    echo "-----------------------------"
    echo "Egyéb paraméterek kiírása:   "
    echo "-----------------------------"
    echo "3. paraméter: $3"
    echo "4. paraméter: $4"
}
 
# Függvény hívása a vegyes paraméterekkel
fuggveny tomb1 tomb2 "beállítás 1" "beállítás 2"

And the output is:

-----------------------------
1. Paramétertömb kilistázása:
-----------------------------
0: 100
1: 200
2: 500
3: több szavas
4: másik három szavas

-----------------------------
2. Paramétertömb kilistázása:
-----------------------------
0: másik tömb
1: 2000
2: ebben is vannak több szavas elemek
3: 2500
4: 3000
5: a-b c

-----------------------------
Egyéb paraméterek kiírása:   
-----------------------------
3. paraméter: beállítás 1
4. paraméter: beállítás 2

The essence of this method is that in the parameters of the function, the arrays were passed by name, not by their extracted values. Then, in rows 12 and 13 in the function, we create the internal variables based on the names obtained.

The disadvantage of this approach, however, is that here we have to work with a fixed parameter sequence in the function, so as we encode it into the algorithm, the parameters must also arrive in that order, otherwise errors will occur. Sure, there are ways to go through all the parameters and examine their type, but that's another story ...

Deleting array elements and arrays

To delete an item, use the following syntax:

unset tomb[4]

In this case, without the dollar sign and the parentheses, we refer to the variable as a store, not to the value in it.

And to delete the whole array, enter:

unset tomb

Here, similarly, we refer to the whole array without the dollar sign and brace.

 

next page we continue to learn about associative arrays ...

 

 

Navigation

This description consists of several pages: