В bash
4.4+ можно было сделать:
readarray -td '' array < <(
((${#array[@]})) && printf -- '-e\0%s\0' "${array[@]}"
)
Здесь использование \0
в качестве разделителя, поскольку переменные bash в любом случае не могут содержать байты NUL. Если вы знаете, что массив не будет пустым, вы можете пропустить ((${#array[@]})) &&
.
Пример:
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")
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")
В zsh
можно было использовать его оператор сжатия массива:
opt=-e
(($#array == 0)) || array=("${(@)opt:^^array}")
Или этот запутанный:
set -o extendedglob # for (#m)
array=("${(Q@)"${(@z)array//(#m)*/-e ${(qq)MATCH}}"}")
Где мы заменяем каждый элемент на-e <the-element-quoted>
(флагом qq
), а затем используем z
для разбора этого цитирования обратно в список элементов (, где -e
и <the-element-quoted>
затем разделил )и Q
, чтобы удалить кавычки (и @
внутри кавычек, используемых для сохранения пустых элементов, если они есть ).
Вы можете немного упростить предложенный цикл:
exclude_args=()
for elem in "${exclude[@]}"; do
exclude_args+=('-e' "$elem")
done
exclude=("${exclude_args[@]}") # Optional, if you want to replace the original array's contents