Skip to main content
added 346 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

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).

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.

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") 

In zsh, you could use its array zipping operator:

opt=-e 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).

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") 

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).

added 346 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

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.

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") 

In zsh, you could use its array zipping operator:

opt=-e 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).

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.

In zsh, you could use its array zipping operator:

opt=-e array=("${(@)opt:^^array}") 

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.

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") 

In zsh, you could use its array zipping operator:

opt=-e 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).

Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

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.

In zsh, you could use its array zipping operator:

opt=-e array=("${(@)opt:^^array}")