In bash 4.4+, you could do:
readarray -td '' array < <( ((${#array[@]})) && printf -- '-e\0%s\0' "${array[@]}" ) Here using \0 as the delimiter as bash variables can't contain NUL bytes anyway. If you know the array is not going to be empty, you can skip the ((${#array[@]})) &&.
Example:
- before:
bash-5.0$ array=($'a\nb' '' 'c d' e) bash-5.0$ typeset -p array declare -a array=([0]=$'a\nb' [1]="" [2]="c d" [3]="e")
- after:
bash-5.0$ typeset -p array declare -a array=([0]="-e" [1]=$'a\nb' [2]="-e" [3]="" [4]="-e" [5]="c d" [6]="-e" [7]="e")
bash-5.0$ typeset -p array declare -a array=([0]="-e" [1]=$'a\nb' [2]="-e" [3]="" [4]="-e" [5]="c d" [6]="-e" [7]="e") In zsh, you could use its array zipping operator:
opt=-e (($#array == 0)) || array=("${(@)opt:^^array}") Or this convoluted one:
set -o extendedglob # for (#m) array=("${(Q@)"${(@z)array//(#m)*/-e ${(qq)MATCH}}"}") Where we replace each element with -e <the-element-quoted> (with the qq flag), and then use z to parse that quoting back into a list of elements (where -e and <the-element-quoted> are then separated out), and Q to remove the quotes (and @ within quotes used to preserve empty elements if any).