Como gerar seqüências de caracteres separadas por vírgula usando expansão bash brace


17

eu gostaria

$ echo a{b,c,d}

para produzir uma lista separada por vírgula como

ab,ac,ad

em vez da saída usual

ab ac ad

Qual é a maneira mais fácil de fazer isso na linha de comando?

Respostas:


9

Supondo que os elementos não contenham espaços, você pode converter espaços em vírgulas:

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

que produz:

ab,ac,ad

Você também pode usar intervalos com caracteres:

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

Isso é especialmente útil se você deseja um alcance maior.


13

Parece que o bash não usa $ IFS para juntar as palavras geradas. Outra técnica seria armazenar as palavras geradas em uma matriz e, em seguida, $ IFS estará em jogo:

Vou usar um subshell para não alterar o IFS desse shell: escolha um dos

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

Isso emite a string separada por vírgula para stdout. Se você deseja capturá-lo:

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

Ele não une as palavras geradas. Esse é o ponto, ele se expande para separar palavras.
Stéphane Chazelas

5

Estou certo de que há muitas maneiras de conseguir isso. Aqui está um método:

echo a{b,c,d} | sed 's/ /,/g'

2

Expanda os elementos como você mostrou e faça um loop sobre eles, adicionando a vírgula a todos, exceto a primeira iteração:

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

Resultado:

ab, ac, ad

Consulte substituição de parâmetros bash .


1

Aqui está uma solução apenas para o bash.

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

A parte antes do ponto e vírgula é atribuída ab ac adà variável INe a segunda parte usa a pesquisa e a substituição para alterar todos os espaços por vírgulas. O //significa todos os jogos, não apenas o primeiro.

Faça tudo em uma subshell (os parênteses) para não poluir seu espaço para nome.


1

Vale a pena notar que, em muitos contextos, uma vírgula à direita é aceitável nessa lista. IF uma vírgula de fuga é aceitável, a maneira mais fácil de manusear a substituição é printf:

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

(Onde some-commandestá um comando que é executado em uma lista separada por vírgula e não se importa com uma vírgula à direita.)

Na verdade, mesmo que você não deva ter uma vírgula, você pode usar printf; você só precisa especificar o número de argumentos que espera, o que o torna mais desajeitado para listas muito longas:

some-command "$(printf %s,%s,%s a{b,c,d} )"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.