You can use the following methods to slice an array in Bash:
- Slice from a start index to a given number of elements:
sliced_array=(“${long_array[@]:start_index:count}”)
- Slice from the beginning:
sliced_array=("${long_array[@]::count}")
- Slice from a specific index to the end:
sliced_array=("${my_array[@]:start_index}")
- Using the awk command: sliced_array=
($(echo "${my_array[@]}" | awk '{for(i=2;i<=4;i++)printf "%s ",$i}'))
- Using for loop:
for ((i = start_index; i <= end_index; i++)); do
sliced_array+=("${my_array[i]}"); done
- Using while loop:
while [ $start_index -le $end_index ]; do
sliced_array+=("${array[start_index]}")
((start_index++)); done
Slicing an array in Bash refers to retrieving a portion of elements from the original array which essentially creates a new array containing only the specified elements. “Array slicing” is a powerful tool for working with a subset of a Bash array. This article will discuss 10 essential methods to show how to slice an array in Bash including 3 “standard array expressions” which are the most popular and fast methods. Also, it will mention the array slicing technique using the “negative index” and commands like “unset” and “awk” to slice a Bash array.
1. Using Array Subsetting Extraction
The array subsetting extraction method extracts a subset of elements to slice a Bash array. It is the most simple and popular method for array slicing from a starting index up to a specific number of elements. The full syntax is ${array[@]:start_index: count} which slices the specified array from the element located at start_index (0-based index) till the number of elements to slice that is defined by count. See the below example to see this syntax in action for a clearer understanding:
#!/bin/bash
#the actual array
food=(pizza burger sandwich hotdog pasta chicken)
#print the array
echo "original elements: ${food[@]}"
#slicing the array
sliced=${food[@]:2:3}
#printing the sliced elements
echo "sliced elements: $sliced"
The script above takes a Bash array called food with 6 elements. Then, the slicing expression ${food[@]:2:3}
is defined and assigned to a variable called sliced which takes 3 elements (sandwich, hotdog, pasta) starting the slicing from index 2 without modifying the original one. Finally, the echo command displays the sliced contents to the command prompt.
2. Using the Syntax ${array[@]:start_index}
It is possible to slice elements of an array from a specified starting index till the very end of that array by using the syntax ${array[@]:start_index}. This essentially starts slicing the array from start_index till the end.
Here’s how to slice an array in Bash using ${array[@]:start_index}
:
#!/bin/bash
# Define an array
my_array=("apple" "orange" "banana" "grape" "kiwi")
#print the original array
echo "original: ${my_array[@]}"
# Slice the array from index 2 (3rd element) to the end
sliced_array=("${my_array[@]:2}")
# Print the sliced array
echo "sliced: ${sliced_array[@]}"
In the above script, after initializing an indexed array called my_array with 5 items, the code sliced_array=("${my_array[@]:2}")
slices the array from the index 2 (banana) to the end (kiwi) and stores the sliced elements in a new array-type variable sliced_array. Finally, it prints the sliced version of the original array to the prompt.
3. Using ${array[@]::end_index} to Slice from the Beginning
To slice a Bash array from the beginning (index 0) until a specified end index, use the syntax ${array[@]::end_index}
which slices the array from index 0 to end_index exclusive. Here’s an example:
#!/bin/bash
# Define an array
fruits=("apple" "orange" "banana" "grape" "kiwi")
# Slice the array from the beginning to index 2 (index 3 exclusive)
sliced_array=("${fruits[@]::3}")
# Print the sliced array
echo "${sliced_array[@]}"
The above script creates an array fruits with fruits=("apple" "orange" "banana" "grape" "kiwi")
and the expression sliced_array=("${fruits[@]::3}")
slices the array from index 0 to index 2 (index 3 exclusive) and stores the items in the sliced_array which is evident after printing the sliced items.
4. Using a Negative Index
In the context of indexed arrays in Bash, the elements can be accessed from the end to the beginning using the negative index. For instance, the syntax ${array[-1]} accesses the last item of the array. Now, this useful concept is capable of slicing an array in Bash like the following Bash script example:
#!/bin/bash
# Define an array
food=("apple" "orange" "banana" "grape" "kiwi")
# Print the food array
echo "original: ${food[@]}"
# Slice the array from the second last element to the end
sliced_array=("${food[@]:(-2)}")
# Print the sliced array
echo "sliced: ${sliced_array[@]}"
In the above script, after the declaration of the food array with 5 items, the expression "${food[@]:(-2)}"
slices the food array from the 2nd last item (grape) at index -2 to the last item (kiwi) at index -1 and the sliced_array variable stores them as array elements. This slices the original array without modifying it. Finally, the echo command prints the two array versions (original and sliced) to reflect the changes.
5. Using “for” Loop
The Bash for loop is an effective tool to iteratively access the elements for goal-specific data manipulation. For instance, the for loop can iteratively slice an array in Bash with the syntax for ((i = start_index; i <= end_index; i++))
. Here’s how to slice a Bash array using for loop:
#!/bin/bash
# Define an array
my_array=("apple" "orange" "banana" "grape" "kiwi")
#print the array
echo "${my_array[@]}"
# Define the start and end indices for slicing
start_index=1
end_index=3
# Initialize an empty array to hold the sliced elements
sliced_array=()
# Slice the array using a for loop
for ((i = start_index; i <= end_index; i++)); do
sliced_array+=("${my_array[i]}")
done
# Print the sliced array
echo "${sliced_array[@]}"
In the above script, the loop for ((i = start_index; i <= end_index; i++))
iterates from the start_index till the end_index and appends the elements to the sliced_array using sliced_array+=("${my_array[i]}")
. Finally, the printing of the “sliced_array” shows that the original array is sliced.
6. Using Variable Index with “for” Loop
It is possible to slice an array in Bash using dynamic conditions such as to only slice the elements of the odd indices, etc. Here, using the variable index concept is useful in that the custom indices of items to be sliced are stored in another array. This is used as a condition by a for loop to iterate over the index and slice the array more dynamically. Below is an example to show this concept in action to slice a Bash array:
#!/bin/bash
old_array=(a b c d e f g h i j) # Sample array
#print the array
echo "original: ${old_array[@]}"
element_index=(1 3 5 7) # Indices 1, 3, 5, and 7 (corresponding to 2nd, 4th, 6th, 8th items)
new_array=()
for index in "${element_index[@]}"; do
new_array+=("${old_array[ index]}")
done
echo "sliced: ${new_array[@]}" # Output the sliced array
The script first declares an array old_array with 10 elements. It then creates an array element_index containing the indices 1, 3, 5, and 7, corresponding to the 2nd, 4th, 6th, and 8th elements in the “old_array”. The for loop iterates over these indices, accessing the corresponding elements from “old_array” and storing them in the new_array. This demonstrates a dynamic slicing approach based on variable indices.
7. Using “while” Loop
Apart from the for loop, the Bash while loop is also a powerful tool to slice an array in Bash by iterating over the indices and selecting elements within that desired range. Here’s an example:
#!/bin/bash
# Define an array
array=("apple" "orange" "banana" "grape" "kiwi")
# Print the sliced array
echo "${array[@]}"
# Define the start and end indices for slicing
start_index=1
end_index=3
# Initialize an empty array to hold the sliced elements
sliced_array=()
# Slice the array using a while loop
while [ $start_index -le $end_index ]; do
sliced_array+=("${array[start_index]}")
((start_index++))
done
# Print the sliced array
echo "${sliced_array[@]}"
In the above script, array=("apple" "orange" "banana" "grape" "kiwi")
initialized an array with 5 elements. Then the loop while [ $start_index -le $end_index ]
iterates over index 1 to 3 (defined by start_index and end_index) and slices the elements to a new array called sliced_array with an increase in every iteration. Finally, printing the 2 arrays shows the success of the slicing operation.
8. Using a Function
The Bash function can combine the necessary commands and expressions to slice a Bash array and execute them by calling the function where the array is passed as the parameter.
Copy the below code to slice an array using a Bash function:
#!/bin/bash
slice_array() {
local array=("${!1}") # Get the array passed as an argument
local start=$2 # Get the starting index
local end=$3 # Get the ending index
# Slice the array using array slicing expression
local sliced_array=("${array[@]:start:end - start + 1}")
# Print the sliced array
echo "${sliced_array[@]}"
}
# Define an array
my_array=("apple" "orange" "banana" "grape" "kiwi")
echo "${my_array[@]}"
# Slice the array from index 1 to 4
sliced=$(slice_array my_array[@] 1 4)
echo "$sliced"
The above code defines a function named slice_array that accepts three arguments: the name of an array, a starting index, and an ending index. The function uses indirect parameter expansion (“${!1}”) to retrieve the array elements and store them in a local array variable. It then applies the array slicing expression "{array[@]:start:end - start + 1}"
to extract a portion of the array and the sliced elements are stored in a local array sliced_array and printed using the echo command.
9. Using the “unset” Command
The unset command is generally used to remove elements of an array to make it clear. However, a smart approach can leverage the slicing of a Bash array using the unset command. Just copy the original array to another array-type variable and remove elements that you don’t want using the unset array[index]
syntax. This will help store the remaining array items in a slicing format while keeping the original array intact.
Here’s an example of slicing an array in Bash using the “unset” command:
#!/bin/bash
# Define an array
original_array=("apple" "orange" "banana" "grape" "kiwi")
# Make a copy of the original array
copied_array=("${original_array[@]}")
#print array
echo "original: ${original_array[@]}"
# Use unset on the copied array to remove 2 elements
unset copied_array[1] # Remove the second element
unset copied_array[3] # Remove the fourth element
# Slice the array (excluding removed elements)
sliced_array=("${copied_array[@]}")
# Print the sliced items
echo "${sliced_array[@]}"
In the above script, after the declaration of the original_array, the expression copied_array=("${original_array[@]}")
makes a duplicate array copied_array by taking elements from the main array. Then the commands unset copied_array[1]
and unset copied_array[3]
remove 2 array elements (directly modifying the copied array). This array is then again copied to another variable “sliced_array” (though optional). That’s how the unset command removes specific elements from the array achieving a sliced array as a result.
10. Using the “awk” Command
The awk command is a useful text-processing tool in Unix and Linux environments. This can also be used to slice an array in Bash. Here’s how:
#!/bin/bash
#define array
my_array=("apple" "orange" "banana" "grape" "kiwi")
#print array
echo ${my_array[@]}
# slicing the array
sliced_array=($(echo "${my_array[@]}" | awk '{for(i=2;i<=4;i++)printf "%s ",$i}'))
echo
#printing the sliced array
echo ${sliced_array[@]}
Here, my_array=("apple" "orange" "banana" "grape" "kiwi")
declares an array with 5 elements. Then the expression ($(echo "${my_array[@]}" | awk '{for(i=2;i<=4;i++)printf "%s ",$i}'))
first expands the array elements separated by spaces and piped to the “awk” command where awk ‘{for(i=2;i<=4;i++)printf “%s “,$i}’ processes the items by iterating from i=2 to i=4 (2nd 3rd 4th element) and printf “%s “,$i only prints the 2nd to 4th item located at indices 1 2 3. These elements are stored in an array variable sliced_array.
Practice Tasks on Array Slicing in Bash
The most effective way to learn Bash array slicing is to practice the slice operation using arrays. Here are some basic slice operation tasks to practice. Try the solutions yourself and share them in the comment section:
- Slice an array to obtain all the elements between the first and last elements.
- Initialize an array with 7 elements. Then define a start_index and an end_index to slice all the elements from the start index to end index inclusive.
- Declare an array numbers=(1 2 3 4 5) and slice all its elements except the last 2 elements. Then slice only the first element.
- Consider an array my_array=(“Hello, World!” “universe” “multiverse”). now, using the array slicing technique, print “world!” and “ive” on the terminal.
Conclusion
This article has discussed 10 various methods to slice an array in Bash by retrieving a range of elements of an array. It has mentioned different array expression syntax, and commands like unset and awk to slice a Bash array. Moreover, it has shown loops like for and while to slice a Bash array iteratively. It also has shown the smart usage of the negative index, and Bash function to slice an array in Bash. Furthermore, it has attached 4 practice problems to work on the concept of array slicing. Hope this article empowers you to work creatively with array subsets for data handling and elevate your scripting mastery within arrays in Bash.
People Also Ask
What exactly is meant by slicing a Bash array?
Array slicing in Bash is a technique that allows retrieving a range of elements from an array while keeping the actual array intact. The sliced elements can be stored for example in another array type variable. Array slicing is useful when you want to work with a subset of elements rather than working with the entire array. To slice a Bash array, use the syntax ${array[@]:start:count}
.
What is the difference between slicing and splitting an array in Bash?
“Array slicing” in Bash is the process of selecting a subset of elements from an array maintaining the original order of the extracted elements. On the other hand, “array splitting” refers to dividing an array into smaller parts based on a pre-defined delimiter or separator.
What is the easiest method to slice an array in Bash from the beginning?
Using the syntax ${array[@]::end_index} is the easiest method to slice an array from the beginning. It slices the array from index 0 to the index number specified by (end_index-1). For example, if you have an array number= (1 2 3 4 5 6 7)
and you use the syntax “${number[@]::4}”
, then it will slice the array from indices 0 to 3 (1 2 3 4).
How to slice an array in Bash?
To slice an array in Bash, use the syntax ${array[@]:start:count}. This will start fetching the array elements from the index specified by start till the number of elements is defined by count. For example: the code ${numbers[@]:2:5}
slices 5 elements from the numbers array starting from the index 2 (inclusive).
Can I slice the first N elements in Bash?
Absolutely. Use the syntax ${my_array[@]:0:N} to slice the first N elements of an array. For instance, consider the array food=(apple banana pie pizza orange sub)
. Using the code ${food[@]:0:3}
will slice the first 3 array elements (apple banana pie) from the original array of 6 elements.
Is it possible to slice an empty array in Bash?
Yes. you can use the array slicing syntax ${array[@]:start:count} to slice an array regardless of its being empty. However, the resulting slice will also be empty. For example, array=()
is an empty array. So, running the command sliced_array=("${empty_array[@]:1:3}")
will also create an empty sliced_array. To verify, print the array length using echo "${#sliced_array[@]}"
and you will get 0.
Related Articles
- How to Convert a JSON Array into Bash Array [5 Methods]
- Master Bash Array of Strings with Spaces [Complete Guide]
- How to Convert String into Array in Bash [8 Methods]
- How to Append to an Array in Bash? [4 Easy Methods]
- How to Clear an Array in Bash [6 Methods]
- How to Filter an Array in Bash? [8 Methods]
- How to Copy an Array in Bash [6 Simple Methods]
- How to Reverse an Array in Bash? [8 Easy Methods]
- Iterate Through a Bash Array Using “foreach” Loop [5 Examples]
- How to Check If an Array is Empty in Bash? [5 Methods]
<< Go Back to Array Operations in Bash | Bash Array | Bash Scripting Tutorial
FUNDAMENTALS A Complete Guide for Beginners
There’s two more slices that might be useful, subsets of what you’ve listed.
List the last N elements of an array: echo “${array[@]: -N”
Remove elements that are multiples of N: unset array[{1..99..N}]
Thanks for your response. I am thrilled you have taken the time to look into my article. Now, as far as the method is concerned to slice the last N elements of an array, the method you mentioned
echo ${array[@]:-N}
will work, however, you have to use an extra space after the colon for the expression to work properly byecho ${array[@]: -N}
since it’s now dealing with negative indices. If not, then, the slicing expression might behave unexpectedly.So, you have to be extra careful. Or you can enclose the negative number inside parenthesis () to avoid such typos. The syntax would be like this:
echo ${array[@]:(-3)}
.As far as your second-mentioned technique, it depends on the step size N and the main thing is that the unset command removes items from the array. But array slicing typically is to extract items of your choice from the original array without modifying it. The method you mentioned alters the original array and is not a direct array slicing method.
Thanks. Hope it helps.
Also newer versions of bash require the nameref type variable instead of the exclamation point indirection:
$ declare -fp slice_array t2
slice_array ()
{
local -n array=”$1″;
local start=$2;
local end=$3;
local sliced_array=(“${array[@]:start:end – start + 1}”);
echo “${sliced_array[@]}”
}
$ declare -a t2=({a..z})
$ slice_array t2 5 10
f g h i j k
$ slice_array t2 -10 -5
q r s t u v
In your mentioned method, the reference is useful after defining the function to see its definition for debugging purposes and what you have. If you use the line before the function, then there’s an error:
#-fp before the function definition:
declare -fp slice_array t2
slice_array ()
{
local -n array="$1";
local start=$2;
local end=$3;
local sliced_array=("${array[@]:start:end - start + 1}");
echo "${sliced_array[@]}"
}
declare -a t2=({a..z})
s=$(slice_array t2 5 10)
w=$(slice_array t2 -10 -5)
Where the function and the passed array is not found by declare -fp
Now if you use the code after defining the function, then you might get something like the following:
slice_array ()
{
## the function scope as before
}
declare -fp slice_array t2
Now, here you see that the code throws an error of t2 not found since the command actually works on the function to display the function definition slice_array definition not the definition of Bash arrays. So after getting t2, it finds out to be an array, not a function and so throws the error.
So, if you omit the t2 then, you will not get any errors in slicing the array.
Thus, you can refer to this modified code:
slice_array ()
{
# THE function scope as before
}
declare -fp slice_array # the t2 term is not mentioned here after the function definition
the final result will look like this:
in summary, it is not necessary to use the nameref declare -fp in the code in which you are slicing an array. You can slice even without the line.
Thank you. For any further queries, leave a message.
Sorry, that was a typo including “t2” on the “declare -fp” statement. I didn’t mean to include that.
Absolutely, alright. These typos are an integral part of working with lines of code. So, feel free to share your thoughts. Thanks again for your feedback and I hope you are clear about your queries.