Como gerar strings separadas por vírgulas usando a expansão de chaves bash

13

Eu gostaria que

$ echo a{b,c,d}

para gerar uma lista separada por vírgula como

ab,ac,ad

em vez do resultado normal

ab ac ad

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

    
por jrennie 26.03.2014 / 21:28

6 respostas

7

Assumindo que os elementos não contêm espaços, você pode traduzir espaços para 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ê quiser um intervalo maior.

    
por 26.03.2014 / 21:41
12

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

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

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

Isso emite a string comma-separated para stdout. Se você quiser capturá-lo:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )
    
por 26.03.2014 / 21:54
3

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

echo a{b,c,d} | sed 's/ /,/g'
    
por 26.03.2014 / 21:41
2

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

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

Resultado:

ab, ac, ad

Veja substituição de parâmetro bash .

    
por 10.08.2018 / 11:07
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 atribui ab ac ad à variável IN e a segunda parte usa pesquisa e substituição para alterar todos os espaços para vírgulas. O // significa todas as correspondências, não apenas a primeira.

Faça tudo em um subshell (os parênteses) para não poluir o seu namespace.

    
por 14.09.2016 / 02:23
1

Vale notar que, em muitos contextos, uma vírgula final é aceitável em tal lista. SE uma vírgula final é aceitável, a maneira mais fácil de lidar com a substituição é printf :

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

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

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

some-command "$(printf %s,%s,%s a{b,c,d} )"
    
por 14.09.2016 / 02:55

Tags