pure-bash-bible/manuscript/chapter2.txt

135 lines
2.1 KiB
Plaintext
Raw Permalink Normal View History

2018-06-20 08:00:33 +02:00
# ARRAYS
2018-06-20 05:03:53 +02:00
## Reverse an array
2018-06-20 05:03:53 +02:00
Enabling `extdebug` allows access to the `BASH_ARGV` array which stores
the current functions arguments in reverse.
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 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 05:03:53 +02:00
**Example Usage:**
```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 05:03:53 +02:00
## Remove duplicate array elements
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+
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 05:03:53 +02:00
**Example Usage:**
```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 05:03:53 +02:00
**Example Function:**
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 05:03:53 +02:00
**Example Usage:**
```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 05:03:53 +02:00
## Cycle through an array
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 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))
}
```
<!-- CHAPTER END -->