2018-06-20 08:00:33 +02:00
|
|
|
|
# ARRAYS
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
## Reverse an array
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
Enabling `extdebug` allows access to the `BASH_ARGV` array which stores
|
|
|
|
|
the current function’s arguments in reverse.
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2019-09-19 17:43:16 +02:00
|
|
|
|
**CAVEAT**: Requires `shopt -s compat44` in `bash` 5.0+.
|
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Function:**
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
```sh
|
|
|
|
|
reverse_array() {
|
|
|
|
|
# Usage: reverse_array "array"
|
|
|
|
|
shopt -s extdebug
|
|
|
|
|
f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@"
|
|
|
|
|
shopt -u extdebug
|
|
|
|
|
}
|
|
|
|
|
```
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Usage:**
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
|
|
|
|
```shell
|
2018-06-20 05:03:53 +02:00
|
|
|
|
$ reverse_array 1 2 3 4 5
|
|
|
|
|
5
|
|
|
|
|
4
|
|
|
|
|
3
|
|
|
|
|
2
|
|
|
|
|
1
|
|
|
|
|
|
|
|
|
|
$ arr=(red blue green)
|
|
|
|
|
$ reverse_array "${arr[@]}"
|
|
|
|
|
green
|
|
|
|
|
blue
|
|
|
|
|
red
|
2018-06-20 04:24:38 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
## Remove duplicate array elements
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
Create a temporary associative array. When setting associative array
|
|
|
|
|
values and a duplicate assignment occurs, bash overwrites the key. This
|
|
|
|
|
allows us to effectively remove array duplicates.
|
|
|
|
|
|
|
|
|
|
**CAVEAT:** Requires `bash` 4+
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2019-09-19 17:43:16 +02:00
|
|
|
|
**CAVEAT:** List order may not stay the same.
|
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Function:**
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
remove_array_dups() {
|
|
|
|
|
# Usage: remove_array_dups "array"
|
|
|
|
|
declare -A tmp_array
|
|
|
|
|
|
|
|
|
|
for i in "$@"; do
|
2019-01-19 10:20:13 +01:00
|
|
|
|
[[ $i ]] && IFS=" " tmp_array["${i:- }"]=1
|
2018-06-20 05:03:53 +02:00
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
printf '%s\n' "${!tmp_array[@]}"
|
|
|
|
|
}
|
2018-06-20 04:24:38 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Usage:**
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 04:40:31 +02:00
|
|
|
|
```shell
|
2018-06-20 05:03:53 +02:00
|
|
|
|
$ remove_array_dups 1 1 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 5
|
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
|
|
5
|
|
|
|
|
|
|
|
|
|
$ arr=(red red green blue blue)
|
|
|
|
|
$ remove_array_dups "${arr[@]}"
|
|
|
|
|
red
|
|
|
|
|
green
|
|
|
|
|
blue
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Random array element
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Function:**
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
```sh
|
|
|
|
|
random_array_element() {
|
|
|
|
|
# Usage: random_array_element "array"
|
|
|
|
|
local arr=("$@")
|
|
|
|
|
printf '%s\n' "${arr[RANDOM % $#]}"
|
|
|
|
|
}
|
2018-06-20 04:24:38 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
**Example Usage:**
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 04:40:31 +02:00
|
|
|
|
```shell
|
2018-06-20 05:03:53 +02:00
|
|
|
|
$ array=(red green blue yellow brown)
|
|
|
|
|
$ random_array_element "${array[@]}"
|
|
|
|
|
yellow
|
|
|
|
|
|
2018-06-20 08:00:33 +02:00
|
|
|
|
# Multiple arguments can also be passed.
|
2018-06-20 05:03:53 +02:00
|
|
|
|
$ random_array_element 1 2 3 4 5 6 7
|
|
|
|
|
3
|
2018-06-20 04:40:31 +02:00
|
|
|
|
```
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
## Cycle through an array
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
Each time the `printf` is called, the next array element is printed. When
|
|
|
|
|
the print hits the last array element it starts from the first element
|
|
|
|
|
again.
|
2018-06-20 04:24:38 +02:00
|
|
|
|
|
2018-06-20 05:03:53 +02:00
|
|
|
|
```sh
|
|
|
|
|
arr=(a b c d)
|
|
|
|
|
|
|
|
|
|
cycle() {
|
|
|
|
|
printf '%s ' "${arr[${i:=0}]}"
|
|
|
|
|
((i=i>=${#arr[@]}-1?0:++i))
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Toggle between two values
|
|
|
|
|
|
|
|
|
|
This works the same as above, this is just a different use case.
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
arr=(true false)
|
|
|
|
|
|
|
|
|
|
cycle() {
|
|
|
|
|
printf '%s ' "${arr[${i:=0}]}"
|
|
|
|
|
((i=i>=${#arr[@]}-1?0:++i))
|
|
|
|
|
}
|
2018-06-20 04:24:38 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<!-- CHAPTER END -->
|
|
|
|
|
|