¿Cómo puedo unir elementos de una matriz Bash en una cadena delimitada?
Si tengo una matriz como esta en Bash:
FOO=( a b c )
¿Cómo uno los elementos con comas? Por ejemplo, producir a,b,c
.
Una función Bash 100% pura que admite delimitadores de varios caracteres es:
function join_by {
local d=${1-} f=${2-}
if shift 2; then
printf %s "$f" "${@/#/$d}"
fi
}
Por ejemplo,
join_by , a b c #a,b,c
join_by ' , ' a b c #a , b , c
join_by ')|(' a b c #a)|(b)|(c
join_by ' %s ' a b c #a %s b %s c
join_by $'\n' a b c #a<newline>b<newline>c
join_by - a b c #a-b-c
join_by '\' a b c #a\b\c
join_by '-n' '-e' '-E' '-n' #-e-n-E-n-n
join_by , #
join_by , a #a
El código anterior se basa en las ideas de @gniourf_gniourf, @AdamKatz, @MattCowell y @x-yuri. Funciona con las opciones errexit
( set -e
) y nounset
( set -u
).
Alternativamente, una función más simple que admita solo un delimitador de un solo carácter sería:
function join_by { local IFS="$1"; shift; echo "$*"; }
Por ejemplo,
join_by , a "b c" d #a,b c,d
join_by / var local tmp #var/local/tmp
join_by , "${FOO[@]}" #a,b,c
Esta solución se basa en la sugerencia original de Pascal Pilz.
Puede encontrar una explicación detallada de las soluciones propuestas anteriormente aquí en " Cómo unir() elementos de matriz en un script bash", un artículo de meleu en dev.to.
Otra solución más:
#!/bin/bash
foo=('foo bar' 'foo baz' 'bar baz')
bar=$(printf ",%s" "${foo[@]}")
bar=${bar:1}
echo $bar
Editar: lo mismo pero para el separador de longitud variable de varios caracteres:
#!/bin/bash
separator=")|(" # e.g. constructing regex, pray it does not contain %s
foo=('foo bar' 'foo baz' 'bar baz')
regex="$( printf "${separator}%s" "${foo[@]}" )"
regex="${regex:${#separator}}" # remove leading separator
echo "${regex}"
# Prints: foo bar)|(foo baz)|(bar baz