Arrays (Bash): verschil tussen versies
Regel 221: | Regel 221: | ||
echo "Entry i+1: ${j[$i+1]}" | echo "Entry i+1: ${j[$i+1]}" | ||
echo "Entry 6: ${j[6]}" | echo "Entry 6: ${j[6]}" | ||
+ | </pre> | ||
+ | |||
+ | == Merge arrays == | ||
+ | |||
+ | Program: | ||
+ | <pre> | ||
+ | i1=(1 2 drie vier) | ||
+ | i2=(4 5 blub Blub) | ||
+ | echo "Array i1: ${i1[@]}" | ||
+ | echo "Array i2: ${i2[@]}" | ||
+ | |||
+ | i3=( "${i1[@]}" "${i2[@]}" ) | ||
+ | echo "Array i3: ${i3[@]}" | ||
+ | </pre> | ||
+ | |||
+ | Output: | ||
+ | |||
+ | <pre> | ||
+ | Array i1: 1 2 drie vier | ||
+ | Array i2: 4 5 blub Blub | ||
+ | Array i3: 1 2 drie vier 4 5 blub Blub | ||
</pre> | </pre> | ||
Versie van 18 okt 2022 16:49
In Bash, an array is a one-dimensional sequence of variables.
No declaration
An array doesn't need to be declared before being used:
j=(1 2 3 blub Blub enough) echo "Array j: ${j[@]}"
Output:
Array j: 1 2 3 blub Blub enough
Note that the entities are printed on one line.
Introduction
#!/bin/bash a=(1 2 "Drie" 4 "Vijf") echo $a # Returns "1" - First item of the array echo $a[0] # Returns "1[0]" - The [0] part is treated as a literal echo ${a[0]} # Returns "1" echo ${a[@]} # Returns "1 2 3 4" - whole array
Nog een beginnetje:
a[0]="Nul" a[1]="Eén" echo $a # Toont alleen eerste element echo $a[0] # Output: Null[0] - Waarschijnlijk niet wat de bedoeling was echo ${a[1]} # OK
Multi-dimensional arrays
Bash doesn't support multidimensional arrays, but you can get a long way with Associative arrays (Bash).
Associative arrays
An associative array is an array where the index doesn't have to be a number. See Associative arrays (Bash) for more.
Length of an array
E.g.:
echo "Length of array j0: ${#j0[@]}"
Return all indices
${!j[@]}
returns all indices. Can be handy as input for a loop. E.g.:
unset j mapfile -t j < <( wp post list --post_type=product --field=ID --posts_per_page=64 ) echo "Number of items: ${!j[@]}"
Output (some output removed):
Number of items: 0 1 2 3 ... 64 65
Something doesn't add up
Note that there are 64, 65 and/or 66 items, depending on how you ask:
unset j mapfile -t j < <( wp post list --post_type=product --field=ID --posts_per_page=64 ) echo "Whole array: ${j[@]}" # 64 IDs echo "Item 5: ${j[5]}" echo "All indices: ${!j[@]}" # 0 to 65 = 66 indices echo "Number of items: ${#j[@]}" # 66
Answer: The first two entries contain NULL. Maybe just some unfortunate null space that mapfile
couldn't avoid → Indeed: WP-CLI creates quite some whitespace. This works better:
unset j mapfile -t j < <( wp post list --post_type=product --field=ID --posts_per_page=64 | grep . ) echo "Whole array: ${j[@]}" echo "Item 5: ${j[5]}" echo "All indices: ${!j[@]}" echo "Number of items: ${#j[@]}"
Loop through array
Dit werkt. Merk op dat $i
de waarde van de cel bevat, niet de index:
array=( one two three ) for i in "${array[@]}" do echo "$i" done
Loop through the index of an array
Rather than going through the entries of an array, let's loop through its index. Note that this is base 0:
array=( one two three ) for i in "${!array[@]}" do echo "Index: $i - Value: ${array[i]}" done
Output:
Index: 0 - Value: one Index: 1 - Value: two Index: 2 - Value: three
Unset
Use unset to destroy an array. Note that the examples below, exhibit some dubious use of associative arrays:
#1/bin/bash # Create & fill an array ######################################## # declare -A tr echo "Newly declared array: ${tr[@]}" tr[1,1]="hoi"; tr[1,2]="doei" echo "Filled array: ${tr[@]}" # Re-declare doesn't reset ######################################## # declare -A tr echo "Array after redeclaring - It doesn't reset the array:" echo ${tr[@]} # Unset array ######################################## # unset tr echo "Array after unset - Now it's empty: ${tr[@]}" # Unset a non-existing array ######################################## # echo "Unsetting a non-existing array doesn't give an error:" unset ik_besta_niet
Uitvoer:
Newly declared array: Filled array: doei hoi Array after redeclaring - It doesn't reset the array: doei hoi Array after unset - Now it's empty: Unsetting a non-existing array doesn't give an error:
Reading output of a command into an array
I want to use WP-CLI command wp post list
to return IDs of products. I want to store these IDs in an array. Subsequently, I want to use parallelisation to do some nifty stuff with these IDs, without having to wait until tomorrow morning for the results.
This doesn't work:
j=$(wp post list --post_type=product --field=ID --posts_per_page=64)
Eventhough echo ${j[@]}
gives a promising result, I think it's just one string and not an array.
This works [1]:
unset j mapfile -t j < <( wp post list --post_type=product --field=ID --posts_per_page=64 | grep . ) echo "Whole array: ${j[@]}" echo "Item 5: ${j[5]}"
With grep .
to trim some leading whitespace.
Arithmatic with arrays
This works, so no (())
black magic today. At least, not here:
i=5 echo "Entry i (=5): ${j[$i]}" echo "Entry i+1: ${j[$i+1]}" echo "Entry 6: ${j[6]}"
Merge arrays
Program:
i1=(1 2 drie vier) i2=(4 5 blub Blub) echo "Array i1: ${i1[@]}" echo "Array i2: ${i2[@]}" i3=( "${i1[@]}" "${i2[@]}" ) echo "Array i3: ${i3[@]}"
Output:
Array i1: 1 2 drie vier Array i2: 4 5 blub Blub Array i3: 1 2 drie vier 4 5 blub Blub
See also
Sources
- https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays
- https://linuxhint.com/associative_array_bash/
- https://stackoverflow.com/questions/11233825/multi-dimensional-arrays-in-bash
- https://stackoverflow.com/questions/3112687/how-to-iterate-over-associative-arrays-in-bash
- https://stackoverflow.com/questions/11426529/reading-output-of-a-command-into-an-array-in-bash