Ora

How to get the last element of an array in shell script?

Published in Shell Array Manipulation 4 mins read

To retrieve the last element of an array in a shell script, the most direct and modern method for Bash (version 4.2 and above), Zsh, and Ksh93 is using negative indexing.

How to Get the Last Element of an Array in Shell Script?

Getting the last element of an array in a shell script can be achieved primarily through two robust methods: negative indexing (for modern shells) or by calculating the array's length and using that to derive the index of the last element.

1. Using Negative Indexing (Modern Shells: Bash 4.2+, Zsh, Ksh93)

The most straightforward and elegant way to access the last element is by using negative indexing. This feature allows you to count elements from the end of the array.

  • Syntax: ${arrayname[-1]}
  • Explanation: The -1 index directly refers to the last element of the array.
  • Compatibility: This method is available in Bash version 4.2 and later, as well as in Zsh and Ksh93. For older Bash versions or other shells, you'll need to use the length-based method.

Example:

#!/bin/bash

# Declare an array
my_array=("apple" "banana" "cherry" "date" "elderberry")

# Get the last element using negative indexing
last_element="${my_array[-1]}"

echo "The last element of the array is: ${last_element}"

# Example with a different array
fruits=("kiwi" "mango" "grape")
echo "Last fruit: ${fruits[-1]}"

2. Using Array Length (Portable Method)

For environments where negative indexing might not be supported (e.g., older Bash versions), or for maximum portability across different shells that support arrays, you can calculate the array's length and then subtract one to get the index of the last element.

  • Syntax: ${arrayname[${#arrayname[@]}-1]}
  • Explanation:
    • ${#arrayname[@]}: This expands to the total number of elements in arrayname.
    • -1: We subtract one from the total count because array indices are zero-based (i.e., the first element is at index 0, the second at 1, and so on). Thus, the last element is at length - 1.
  • Compatibility: This method works in Bash (all versions that support arrays), Zsh, and Ksh. It is highly portable among shells that implement array functionality.

Example:

#!/bin/bash

# Declare an array
my_array=("red" "green" "blue" "yellow")

# Get the total number of elements in the array
array_length="${#my_array[@]}"

# Calculate the index of the last element
last_index=$((array_length - 1))

# Access the last element using its index
last_element="${my_array[last_index]}"

echo "The last element of the array is: ${last_element}"

# Concise version
items=("one" "two" "three")
echo "Last item (concise): ${items[${#items[@]}-1]}"

Practical Considerations

  • Empty Arrays: If an array is empty, accessing ${arrayname[-1]} or ${arrayname[${#arrayname[@]}-1]} will typically result in an empty string (no output), as there is no element at that index. No error is usually thrown for accessing an out-of-bounds index in Bash arrays; it simply expands to null.
  • Sparse Arrays: Both methods correctly identify the last assigned element in a sparse array. For instance, if my_array=( [2]="alpha" [5]="beta" ), both methods will return "beta". The length-based method counts the total number of assigned elements, and negative indexing works relative to the highest index.

Comparison of Methods

Feature Negative Indexing (${arrayname[-1]}) Length-based Indexing (${arrayname[${#arrayname[@]}-1]})
Readability High (direct, intuitive) Moderate (requires understanding of length and zero-based index)
Conciseness High Moderate
Bash Compatibility Bash 4.2+ All Bash versions supporting arrays
Zsh Compatibility Yes Yes
Ksh93 Compatibility Yes Yes
Primary Use Case Modern scripts, ease of use Maximum portability, older shell compatibility

For general shell scripting, especially with modern Bash versions, utilizing ${arrayname[-1]} is the most recommended approach due to its simplicity and clarity.

For more detailed information on Bash array handling, refer to the GNU Bash Manual.