Skip to main content
2 of 6
added 564 characters in body
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

You can get the number of operation down ever so slightly, and skip the call to seq:

for (( i = 1; i < ${#myarr[@]} - 1; ++i )); do
    newarr+=( "${myarr[i]}" "${myarr[i]}" )
done
newarr=( "${myarr[0]}" "${newarr[@]}" "${myarr[-1]}" )

This assumes that newarr is empty to start with. Do unset newarry first if it's not.

As a function (this modifies the array that is passed):

dup_interal_items () {
    typeset -n arr=$1
    local tmparr

    for (( i = 1; i < ${#arr[@]} - 1; ++i )); do
        tmparr+=( "${arr[i]}" "${arr[i]}" )
    done
    arr=( "${arr[0]}" "${tmparr[@]}" "${arr[-1]}" )
}

The name of the array is passed into the function and the name-reference variable arr is used to access the elements in the array. At the end, the original array is updated to contain the result.

Note that you can't call this function with an array called arr due to the particular name scoping rules used by bash. You may want to rename the arr variable in the function if this is an issue.

Testing:

$ myarr=( 1 2 3 "here we go" )
$ dup_interal_items myarr
$ printf 'Element: %s\n' "${myarr[@]}"
Element: 1
Element: 2
Element: 2
Element: 3
Element: 3
Element: here we go
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k