Comment générer des chaînes séparées par des virgules à l'aide de l'expansion d'accolade bash

17

J'aimerais

$ echo a{b,c,d}

pour afficher une liste séparée par des virgules comme

ab,ac,ad

au lieu de la sortie habituelle

ab ac ad

Quelle est la façon la plus simple de le faire sur la ligne de commande?

jrennie
la source

Réponses:

9

En supposant que les éléments ne contiennent pas d'espaces, vous pouvez traduire les espaces en virgules:

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

qui produit:

ab,ac,ad

Vous pouvez également utiliser des plages de caractères:

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

Ceci est particulièrement utile si vous souhaitez une gamme plus large.

devnull
la source
13

Il semble que bash n'utilise pas $ IFS pour joindre les mots générés. Une autre technique serait de stocker les mots générés dans un tableau puis $ IFS sera en jeu:

Je vais utiliser un sous-shell donc je ne modifie pas l'IFS de ce shell: choisissez l'un des

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

Cela émet la chaîne séparée par des virgules vers stdout. Si vous voulez le capturer:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )
glenn jackman
la source
Il ne joint pas du tout les mots générés. C'est tout le problème, il se développe pour séparer les mots.
Stéphane Chazelas
5

Je suis sûr qu'il existe de nombreuses façons d'y parvenir. Voici une méthode:

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

Développez les éléments comme vous l'avez montré, puis bouclez-les, en ajoutant la virgule à tous sauf la première itération:

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

Résultat:

ab, ac, ad

Voir substitution de paramètres bash .

Marki
la source
1

Voici une solution bash uniquement.

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

La partie avant le point-virgule assigne ab ac adà la variable INet la deuxième partie utilise la recherche et le remplacement pour remplacer tous les espaces par des virgules. Cela //signifie tous les matchs, pas seulement le premier.

Faites tout cela dans un sous-shell (les parenthèses englobantes) pour ne pas polluer votre espace de noms.

erg
la source
1

Il convient de noter que dans de nombreux contextes, une virgule de fin est acceptable dans une telle liste. SI une virgule de fin est acceptable, la façon la plus simple de gérer la substitution est printf:

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

(Où some-commandest une commande qui s'exécute sur une liste séparée par des virgules et ne se soucie pas d'une virgule de fin.)

En fait, même si vous ne devez pas avoir de virgule de fin, vous pouvez utiliser printf; il vous suffit de spécifier le nombre d'arguments que vous attendez, ce qui le rend plus maladroit pour les très longues listes:

some-command "$(printf %s,%s,%s a{b,c,d} )"
Caractère générique
la source