Cómo generar cadenas separadas por comas utilizando la expansión bash brace

17

me gustaría

$ echo a{b,c,d}

para generar una lista separada por comas como

ab,ac,ad

en lugar de la salida habitual

ab ac ad

¿Cuál es la forma más fácil de hacer eso en la línea de comando?

jrennie
fuente

Respuestas:

9

Suponiendo que los elementos no contienen espacios, puede traducir espacios a comas:

echo a{b,c,d} | tr ' ' ,

que produce:

ab,ac,ad

También puede usar rangos con caracteres:

echo a{b..d} | tr ' ' ,

Esto es especialmente útil si desea un rango mayor.

devnull
fuente
13

Parece que bash no usa $ IFS para unir las palabras generadas. Otra técnica sería almacenar las palabras generadas en una matriz y luego $ IFS estará en juego:

Voy a usar un subshell para no alterar el IFS de este shell: elija uno de

( words=( a{b,c,d} ); IFS=,; echo "${words[*]}" )
( set -- a{b,c,d}; IFS=,; echo "$*" )

Eso emite la cadena separada por comas a stdout. Si quieres capturarlo:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )
Glenn Jackman
fuente
No , no se unen a las palabras generadas en absoluto. De eso se trata, se expande para separar las palabras.
Stéphane Chazelas
5

Estoy seguro de que hay muchas maneras de lograr esto. Aquí hay un método:

echo a{b,c,d} | sed 's/ /,/g'
Timothy Martin
fuente
2

Expanda los elementos como mostró y luego repítelos, agregando la coma a todos menos a la primera iteración:

for i in a{b,c,d}; do
  u="${u:+$u, }$i"
done
echo "$u"

Resultado:

ab, ac, ad

Ver sustitución de parámetros bash .

Marki
fuente
1

Aquí hay una solución solo para bash.

(IN=$(echo a{b,c,d}); echo ${IN// /,})
# ab,ac,ad

La parte anterior al punto y coma se asigna ab ac ada la variable INy la segunda parte utiliza la búsqueda y reemplazo para cambiar todos los espacios a comas. El //significa que todos los partidos, no sólo el primero.

Hágalo todo en un subshell (los paréntesis adjuntos) para no contaminar su espacio de nombres.

ergio
fuente
1

Vale la pena señalar que en muchos contextos, una coma final es aceptable en dicha lista. SI una coma final es aceptable, la forma más fácil de manejar la sustitución es printf:

some-command "$(printf %s, a{b,c,d} )"

(¿Dónde some-commandestá un comando que se ejecuta en una lista separada por comas y no le importa una coma final?)

En realidad, incluso si no debe tener una coma final, puede usarla printf; solo necesita especificar el número de argumentos que espera, lo que lo hace más torpe para listas muy largas:

some-command "$(printf %s,%s,%s a{b,c,d} )"
Comodín
fuente