Shell script: How to save loop output to array - arrays

This is my simple shell script. The objective is to split string "RANDOM948" as array so that I can manipulate any character in string "RANDOM948".
ubuntu#Ubuntu:~$ cat -n longscript.sh
1 string="RANDOM948"
2
3 c1=${string:0:1}
4 c2=${string:1:1}
5 c3=${string:2:1}
6 c4=${string:3:1}
7 c5=${string:4:1}
8 c6=${string:5:1}
9 c7=${string:6:1}
10 c8=${string:7:1}
11 c9=${string:8:1}
12
13 echo $c9 $c4 $c1
ubuntu#Ubuntu:~$
ubuntu#Ubuntu:~$ ./longscript.sh
8 D R
ubuntu#Ubuntu:~$
I believe this can be simplify by using for loop. This is my attempt. However, I have no idea how to save the loop output as array.
ubuntu#Ubuntu:~$ cat -n testscript.sh
1 string="RANDOM948"
2
3 for i in {1..9}
4 do
5 echo c$i=$\{string:`expr $i - 1`:1}
6 done
7
8 # echo $c9 $c4 $c1
ubuntu#Ubuntu:~$
ubuntu#Ubuntu:~$ ./testscript.sh
c1=${string:0:1}
c2=${string:1:1}
c3=${string:2:1}
c4=${string:3:1}
c5=${string:4:1}
c6=${string:5:1}
c7=${string:6:1}
c8=${string:7:1}
c9=${string:8:1}
ubuntu#Ubuntu:~$
UPDATE: New code as advised by #sos
I've updated this code with new line (5 & 6), however it still doesn't work
ubuntu#Ubuntu:~$ cat -n testscript.sh
1 string="RANDOM948"
2
3 for i in {1..9}
4 do
5 typeset -a c
6 c[${i}]=$\{string:`expr $i - 1`:1}
7 done
8
9 echo TEST OUTPUT $c9 $c4 $c1
ubuntu#Ubuntu:~$
ubuntu#Ubuntu:~$
ubuntu#Ubuntu:~$ ./testscript.sh
TEST OUTPUT
ubuntu#Ubuntu:~$

replace
echo c${i}
with
typeset -a c # declare a indexed array
c[${i}]=...

Here's what I get
set -x
for i in {1..9}
do
c[${i}]=${string:`expr $i - 1`:1}
done
set +x
+ expr 1 - 1
+ c[1]=R
+ expr 2 - 1
+ c[2]=A
+ expr 3 - 1
+ c[3]=N
+ expr 4 - 1
+ c[4]=D
+ expr 5 - 1
+ c[5]=O
+ expr 6 - 1
+ c[6]=M
+ expr 7 - 1
+ c[7]=9
+ expr 8 - 1
+ c[8]=4
+ expr 9 - 1
+ c[9]=8
Note: It's considered "unusual" to begin an array index at 1 rather than 0

you will do yourself and others a favor if you identify what is running your script by using a shebang line e.g.
#!/bin/bash
as the first line in your script. In any case, the below example may help you.
cat ./looptest.sh
note the #! line....
#!/bin/bash
for i in {0..9}
do
myArray[$i]="hello_$i"
echo set the value of myArray[$i]
done
echo the value of myArray[4] is ${myArray[4]}
Here's the output:
set the value of myArray[0]
set the value of myArray[1]
set the value of myArray[2]
set the value of myArray[3]
set the value of myArray[4]
set the value of myArray[5]
set the value of myArray[6]
set the value of myArray[7]
set the value of myArray[8]
set the value of myArray[9]
the value of myArray[4] is hello_4

Related

Picking input record fields with AWK

Let's say we have a shell variable $x containing a space separated list of numbers from 1 to 30:
$ x=$(for i in {1..30}; do echo -n "$i "; done)
$ echo $x
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
We can print the first three input record fields with AWK like this:
$ echo $x | awk '{print $1 " " $2 " " $3}'
1 2 3
How can we print all the fields starting from the Nth field with AWK? E.g.
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
EDIT: I can use cut, sed etc. to do the same but in this case I'd like to know how to do this with AWK.
Converting my comment to answer so that solution is easy to find for future visitors.
You may use this awk:
awk '{for (i=3; i<=NF; ++i) printf "%s", $i (i<NF?OFS:ORS)}' file
or pass start position as argument:
awk -v n=3 '{for (i=n; i<=NF; ++i) printf "%s", $i (i<NF?OFS:ORS)}' file
Version 4: Shortest is probably using sub to cut off the first three fields and their separators:
$ echo $x | awk 'sub(/^ *([^ ]+ +){3}/,"")'
Output:
4 5 6 7 8 9 ...
This will, however, preserve all space after $4:
$ echo "1 2 3 4 5" | awk 'sub(/^ *([^ ]+ +){3}/,"")'
4 5
so if you wanted the space squeezed, you'd need to, for example:
$ echo "1 2 3 4 5" | awk 'sub(/^ *([^ ]+ +){3}/,"") && $1=$1'
4 5
with the exception that if there are only 4 fields and the 4th field happens to be a 0:
$ echo "1 2 3 0" | awk 'sub(/^ *([^ ]+ +){3}/,"")&&$1=$1'
$ [no output]
in which case you'd need to:
$ echo "1 2 3 0" | awk 'sub(/^ *([^ ]+ +){3}/,"") && ($1=$1) || 1'
0
Version 1: cut is better suited for the job:
$ cut -d\ -f 4- <<<$x
Version 2: Using awk you could:
$ echo -n $x | awk -v RS=\ -v ORS=\ 'NR>=4;END{printf "\n"}'
Version 3: If you want to preserve those varying amounts of space, using GNU awk you could use split's fourth parameter seps:
$ echo "1 2 3 4 5 6 7" |
gawk '{
n=split($0,a,FS,seps) # actual separators goes to seps
for(i=4;i<=n;i++) # loop from 4th
printf "%s%s",a[i],(i==n?RS:seps[i]) # get fields from arrays
}'
Adding one more approach to add all value into a variable and once all fields values are done with reading just print the value of variable. Change the value of n= as per from which field onwards you want to get the data.
echo "$x" |
awk -v n=3 '{val="";for(i=n; i<=NF; i++){val=(val?val OFS:"")$i};print val}'
With GNU awk, you can use the join function which has been a built-in include since gawk 4.1:
x=$(seq 30 | tr '\n' ' ')
echo "$x" | gawk '#include "join"
{split($0, arr)
print join(arr, 4, length(arr), "|")}
'
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
(Shown here with a '|' instead of a ' ' for clarity...)
Alternative way of including join:
echo "$x" | gawk -i join '{split($0, arr); print join(arr, 4, length(arr), "|")}'
Using gnu awk and gensub:
echo $x | awk '{ print gensub(/^([[:digit:]]+[[:space:]]){3}(.*$)/,"\\2",$0)}'
Using gensub, split the string into two sections based on regular expressions and print the second section only.

How to add a value into the middle of an array?

Hello I have the following array:
array=(1 2 3 4 5 7 8 9 12 13)
I execute this for loop:
for w in ${!array[#]}
do
comp=$(echo "${array[w+1]} - ${array[w]} " | bc)
if [ $comp = 1 ]; then
/*???*/
else
/*???*/
fi
done
What I would like to do is to insert a value when the difference between two consecutive elements is not = 1
How can I do it?
Many thanks.
Just create a loop from the minimum to the maximum values and fill the gaps:
array=(1 2 3 4 5 7 8 9 12 13)
min=${array[0]}
max=${array[-1]}
new_array=()
for ((i=min; i<=max; i++)); do
if [[ " ${array[#]} " =~ " $i " ]]; then
new_array+=($i)
else
new_array+=(0)
fi
done
echo "${new_array[#]}"
This creates a new array $new_array with the values:
1 2 3 4 5 0 7 8 9 0 0 12 13
This uses the trick in Check if an array contains a value.
You can select parts of the original array with ${arr[#]:index:count}.
Select the start, insert a new element, add the end.
To insert an element after index i=5 (the fifth element)
$ array=(1 2 3 4 5 7 8 9 12 13)
$ i=5
$ arr=("${array[#]:0:i}") ### take the start of the array.
$ arr+=( 0 ) ### add a new value ( may use $((i+1)) )
$ arr+=("${array[#]:i}") ### copy the tail of the array.
$ array=("${arr[#]}") ### transfer the corrected array.
$ printf '<%s>' "${array[#]}"; echo
<1><2><3><4><5><6><7><8><9><12><13>
To process all the elements, just do a loop:
#!/bin/bash
array=(1 2 3 4 5 7 8 9 12 13)
for (( i=1;i<${#array[#]};i++)); do
if (( array[i] != i+1 ));
then arr=("${array[#]:0:i}") ### take the start of the array.
arr+=( "0" ) ### add a new value
arr+=("${array[#]:i}") ### copy the tail of the array.
# echo "head $i ${array[#]:0:i}" ### see the array.
# echo "tail $i ${array[#]:i}"
array=("${arr[#]}") ### transfer the corrected array.
fi
done
printf '<%s>' "${array[#]}"; echo
$ chmod u+x ./script.sh
$ ./script.sh
<1><2><3><4><5><0><7><8><9><10><0><0><13>
There does not seem to be a way to insert directly into an array. You can append elements to another array instead though:
result=()
for w in ${!array[#]}; do
result+=("${array[w]}")
comp=$(echo "${array[w+1]} - ${array[w]} " | bc)
if [ $comp = 1 ]; then
/* probably leave empty */
else
/* handle missing digits */
fi
done
As a final step, you can assign result back to the original array.

bash + awk : looping over an array of 4 elements that returns size of 1?

I have the following script which uses awk to match fields with user input
NB=$#
FILE=myfile
#GET INPUT
if [ $NB -eq 1 ]
then
A=`awk -F "\t" -v town="$1" 'tolower($3) ~ tolower(town) {print NR}' $FILE`
fi
If I print the output, it reads :
7188 24369 77205 101441
Which is what I expected. Then if I do the following:
IFS=' '
array=($A)
echo ${#array[#]}
I actually get a length of 1 (?). Furthermore, if I try:
for x in $array
do
echo $x
done
It actually prints out :
7188
24369
77205
101441
How can I have it return the length of 4. I don't understand how the for...in works if there's only 1 element?
EDIT :
echo $A | od -c before I create the array is:
0000000 7 1 8 8 2 4 3 6 9 7 7 2 0 5
0000020 1 0 1 4 4 1 \n
0000030
echo $A | od -c after I create the array is:
0000000 7 1 8 8 \n 2 4 3 6 9 \n 7 7 2 0 5
0000020 \n 1 0 1 4 4 1 \n
0000030
It is because returned output from awk is newline (\n) delimited instead of space delimited. So if you have IFS like this instead:
IFS=$'\n' # newline between quotes
Then it will echo array length = 4 as you are expecting.

How can I find the sum of the elements of an array in Bash?

I am trying to add the elements of an array that is defined by user input from the read -a command. How can I do that?
read -a array
tot=0
for i in ${array[#]}; do
let tot+=$i
done
echo "Total: $tot"
Given an array (of integers), here's a funny way to add its elements (in bash):
sum=$(IFS=+; echo "$((${array[*]}))")
echo "Sum=$sum"
e.g.,
$ array=( 1337 -13 -666 -208 -408 )
$ sum=$(IFS=+; echo "$((${array[*]}))")
$ echo "$sum"
42
Pro: No loop, no subshell!
Con: Only works with integers
Edit (2012/12/26).
As this post got bumped up, I wanted to share with you another funny way, using dc, which is then not restricted to just integers:
$ dc <<< '[+]sa[z2!>az2!>b]sb1 2 3 4 5 6 6 5 4 3 2 1lbxp'
42
This wonderful line adds all the numbers. Neat, eh?
If your numbers are in an array array:
$ array=( 1 2 3 4 5 6 6 5 4 3 2 1 )
$ dc <<< '[+]sa[z2!>az2!>b]sb'"${array[*]}lbxp"
42
In fact there's a catch with negative numbers. The number '-42' should be given to dc as _42, so:
$ array=( -1.75 -2.75 -3.75 -4.75 -5.75 -6.75 -7.75 -8.75 )
$ dc <<< '[+]sa[z2!>az2!>b]sb'"${array[*]//-/_}lbxp"
-42.00
will do.
Pro: Works with floating points.
Con: Uses an external process (but there's no choice if you want to do non-integer arithmetic — but dc is probably the lightest for this task).
My code (which I actually utilize) is inspired by answer of gniourf_gniourf. I personally consider this more clear to read/comprehend, and to modify. Accepts also floating points, not just integers.
Sum values in array:
arr=( 1 2 3 4 5 6 7 8 9 10 )
IFS='+' sum=$(echo "scale=1;${arr[*]}"|bc)
echo $sum # 55
With small change, you can get the average of values:
arr=( 1 2 3 4 5 6 7 8 9 10 )
IFS='+' avg=$(echo "scale=1;(${arr[*]})/${#arr[#]}"|bc)
echo $avg # 5.5
gniourf_gniourf's answer is excellent since it doesn't require a loop or bc. For anyone interested in a real-world example, here's a function that totals all of the CPU cores reading from /proc/cpuinfo without messing with IFS:
# Insert each processor core count integer into array
cpuarray=($(grep cores /proc/cpuinfo | awk '{print $4}'))
# Read from the array and replace the delimiter with "+"
# also insert 0 on the end of the array so the syntax is correct and not ending on a "+"
read <<< "${cpuarray[#]/%/+}0"
# Add the integers together and assign output to $corecount variable
corecount="$((REPLY))"
# Echo total core count
echo "Total cores: $corecount"
I also found the arithmetic expansion works properly when calling the array from inside the double parentheses, removing the need for the read command:
cpuarray=($(grep cores /proc/cpuinfo | awk '{print $4}'))
corecount="$((${cpuarray[#]/%/+}0))"
echo "Total cores: $corecount"
Generic:
array=( 1 2 3 4 5 )
sum="$((${array[#]/%/+}0))"
echo "Total: $sum"
I'm a fan of brevity, so this is what I tend to use:
IFS="+";bc<<<"${array[*]}"
It essentially just lists the data of the array and passes it into BC which evaluates it. The "IFS" is the internal field separate, it essentially specifies how to separate arrays, and we said to separate them with plus signs, that means when we pass it into BC, it receives a list of numbers separated by plus signs, so naturally it adds them together.
Another dc & bash method:
arr=(1 3.88 7.1 -1)
dc -e "0 ${arr[*]/-/_} ${arr[*]/*/+} p"
Output:
10.98
The above runs the expression 0 1 3.88 7.1 _1 + + + + p with dc. Note the dummy value 0 because there's one too many +s, and also note the usual negative number prefix - must be changed to _ in dc.
arr=(1 2 3) //or use `read` to fill the array
echo Sum of array elements: $(( ${arr[#]/%/ +} 0))
Sum of array elements: 6
Explanation:
"${arr[#]/%/ +}" will return 1 + 2 + 3 +
By adding additional zero at the end we will get 1 + 2 + 3 + 0
By wrapping this string with BASH's math operation like this$(( "${arr[#]/%/ +} 0")), it will return the sum instead
This could be used for other math operations.
For subtracting just use - instead
For multiplication use * and 1 instead of 0
Can be used with logic operators too.
BOOL AND EXAMPLE - check if all items are true (1)
arr=(1 0 1)
if [[ $((${arr[#]/%/ &} 1)) -eq 1 ]]; then echo "yes"; else echo "no"; fi
This will print: no
BOOL OR EXAMPLE - check if any item is true (1)
arr=(1 0 0)
if [[ $((${arr[#]/%/ |} 0)) -eq 1 ]]; then echo "yes"; else echo "no"; fi
This will print: yes
A simple way
function arraySum
{
sum=0
for i in ${a[#]};
do
sum=`expr $sum + $i`
done
echo $sum
}
a=(7 2 3 9)
echo -n "Sum is = "
arraySum ${a[#]}
I find this very simple using an increasing variable:
result2=0
for i in ${lineCoffset[#]};
do
result2=$((result2+i))
done
echo $result2

How to slice an array in Bash

Looking the "Array" section in the bash(1) man page, I didn't find a way to slice an array.
So I came up with this overly complicated function:
#!/bin/bash
# #brief: slice a bash array
# #arg1: output-name
# #arg2: input-name
# #args: seq args
# ----------------------------------------------
function slice() {
local output=$1
local input=$2
shift 2
local indexes=$(seq $*)
local -i i
local tmp=$(for i in $indexes
do echo "$(eval echo \"\${$input[$i]}\")"
done)
local IFS=$'\n'
eval $output="( \$tmp )"
}
Used like this:
$ A=( foo bar "a b c" 42 )
$ slice B A 1 2
$ echo "${B[0]}" # bar
$ echo "${B[1]}" # a b c
Is there a better way to do this?
See the Parameter Expansion section in the Bash man page. A[#] returns the contents of the array, :1:2 takes a slice of length 2, starting at index 1.
A=( foo bar "a b c" 42 )
B=("${A[#]:1:2}")
C=("${A[#]:1}") # slice to the end of the array
echo "${B[#]}" # bar a b c
echo "${B[1]}" # a b c
echo "${C[#]}" # bar a b c 42
echo "${C[#]: -2:2}" # a b c 42 # The space before the - is necesssary
Note that the fact that a b c is one array element (and that it contains an extra space) is preserved.
There is also a convenient shortcut to get all elements of the array starting with specified index. For example "${A[#]:1}" would be the "tail" of the array, that is the array without its first element.
version=4.7.1
A=( ${version//\./ } )
echo "${A[#]}" # 4 7 1
B=( "${A[#]:1}" )
echo "${B[#]}" # 7 1
Array slicing like in Python (From the rebash library):
array_slice() {
local __doc__='
Returns a slice of an array (similar to Python).
From the Python documentation:
One way to remember how slices work is to think of the indices as pointing
between elements, with the left edge of the first character numbered 0.
Then the right edge of the last element of an array of length n has
index n, for example:
```
+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
```
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice 1:-2 "${a[#]}")
1 2 3
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice 0:1 "${a[#]}")
0
>>> local a=(0 1 2 3 4 5)
>>> [ -z "$(array.slice 1:1 "${a[#]}")" ] && echo empty
empty
>>> local a=(0 1 2 3 4 5)
>>> [ -z "$(array.slice 2:1 "${a[#]}")" ] && echo empty
empty
>>> local a=(0 1 2 3 4 5)
>>> [ -z "$(array.slice -2:-3 "${a[#]}")" ] && echo empty
empty
>>> [ -z "$(array.slice -2:-2 "${a[#]}")" ] && echo empty
empty
Slice indices have useful defaults; an omitted first index defaults to
zero, an omitted second index defaults to the size of the string being
sliced.
>>> local a=(0 1 2 3 4 5)
>>> # from the beginning to position 2 (excluded)
>>> echo $(array.slice 0:2 "${a[#]}")
>>> echo $(array.slice :2 "${a[#]}")
0 1
0 1
>>> local a=(0 1 2 3 4 5)
>>> # from position 3 (included) to the end
>>> echo $(array.slice 3:"${#a[#]}" "${a[#]}")
>>> echo $(array.slice 3: "${a[#]}")
3 4 5
3 4 5
>>> local a=(0 1 2 3 4 5)
>>> # from the second-last (included) to the end
>>> echo $(array.slice -2:"${#a[#]}" "${a[#]}")
>>> echo $(array.slice -2: "${a[#]}")
4 5
4 5
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice -4:-2 "${a[#]}")
2 3
If no range is given, it works like normal array indices.
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice -1 "${a[#]}")
5
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice -2 "${a[#]}")
4
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice 0 "${a[#]}")
0
>>> local a=(0 1 2 3 4 5)
>>> echo $(array.slice 1 "${a[#]}")
1
>>> local a=(0 1 2 3 4 5)
>>> array.slice 6 "${a[#]}"; echo $?
1
>>> local a=(0 1 2 3 4 5)
>>> array.slice -7 "${a[#]}"; echo $?
1
'
local start end array_length length
if [[ $1 == *:* ]]; then
IFS=":"; read -r start end <<<"$1"
shift
array_length="$#"
# defaults
[ -z "$end" ] && end=$array_length
[ -z "$start" ] && start=0
(( start < 0 )) && let "start=(( array_length + start ))"
(( end < 0 )) && let "end=(( array_length + end ))"
else
start="$1"
shift
array_length="$#"
(( start < 0 )) && let "start=(( array_length + start ))"
let "end=(( start + 1 ))"
fi
let "length=(( end - start ))"
(( start < 0 )) && return 1
# check bounds
(( length < 0 )) && return 1
(( start < 0 )) && return 1
(( start >= array_length )) && return 1
# parameters start with $1, so add 1 to $start
let "start=(( start + 1 ))"
echo "${#: $start:$length}"
}
alias array.slice="array_slice"
At the risk of beating a dead horse, I was inspired by #jandob's answer and made this version that
Is simpler (doesn't have so much shift logic or rewriting of variables as often).
Respects quoted strings without dealing with IFS (-r mode only).
Allows the user to specify [start, end) slicing or [start, length] slicing via -l flag.
Allows you to echo the resulting array (default behavior), or "return" it into a new array for use in the calling parent (via -r slicedArray).
Note: namerefs are only supported in Bash >= 4.3. To support earlier versions of Bash (i.e. Mac without Brew's bash), you'll need to use indirection instead: use a temp var to access array parameters, e.g. declare arrValuesCmd="$1[#]"; declare arr=("${!arrValuesCmd}"), and use eval for return values, e.g. eval $retArrName='("${newArr[#]}")' (note the single quotes around the array declaration).
array.slice() {
# array.slice [-l] [-r returnArrayName] myArray 3 5
# Default functionality is to use second number as end index for slice (exclusive).
# Can instead use second number as length by passing `-l` flag.
# `echo` doesn't maintain quoted entries, so pass in `-r returnArrayName` to keep them.
declare isLength
declare retArrName
declare OPTIND=1
while getopts "lr:" opt; do
case "$opt" in
l)
# If `end` is slice length instead of end index
isLength=true
;;
r)
retArrName="$OPTARG"
;;
esac
done
shift $(( OPTIND - 1 ))
declare -n arr="$1"
declare start="$2"
declare end="$3"
declare arrLength="${#arr[#]}"
declare newArr=()
declare newArrLength
# Bash native slicing:
# Positive index values: ${array:start:length}
# Negative index values: ${array: start: length}
# To use negative values, a space is required between `:` and the variable
# because `${var:-3}` actually represents a default value,
# e.g. `myVar=${otherVal:-7}` represents (pseudo-code) `myVar=otherVal || myVar=7`
if [[ -z "$end" ]]; then
# If no end is specified (regardless of `-l`/length or index), default to the rest of the array
newArrLength="$arrLength"
elif [[ -n "$isLength" ]]; then
# If specifying length instead of end-index, use native bash array slicing
newArrLength="$(( end ))"
else
# If specifying end-index, use custom slicing based on a range of [start, end):
newArrLength="$(( end - start ))"
fi
newArr=("${arr[#]: start: newArrLength}")
if [[ -n "$retArrName" ]]; then
declare -n retArr="$retArrName"
retArr=("${newArr[#]}")
else
echo "${newArr[#]}"
fi
}
Examples:
myArray=(x y 'a b c' z 5 14) # length=6
array.slice myArray 2 4
# > a b c z
array.slice -l myArray 3 2
# > z 5
# Note: Output was manually quoted to show the result more clearly.
# Actual stdout content won't contain those quotes, which is
# why the `-r returnArray` option was added.
array.slice -r slicedArray myArray -5 -3 # equivalent of [2, 4)
# > (null)
echo -e "myArray (length=${#myArray[#]}): ${myArray[#]} \nslicedArray (length=${#slicedArray[#]}): ${slicedArray[#]}"
# > myArray (length=6): x y 'a b c' z 5 14
# > slicedArray (length=2): 'a b c' z
array.slice -lr slicedArray myArray -5 3 # length instead of index, equivalent of [2, 5)
# > (null)
echo -e "myArray (length=${#myArray[#]}): ${myArray[#]} \nslicedArray (length=${#slicedArray[#]}): ${slicedArray[#]}"
# > myArray (length=6): x y 'a b c' z 5 14
# > slicedArray (length=3): 'a b c' z 5

Resources