Você raramente precisa de um loop no bash:
echo {0..55..5} | sed 's/ /,/g'
Esse script funciona muito bem e eu o modifiquei para aumentar em 5. Meu problema é que não preciso da última vírgula no final e não sei como remover isso.
for ((i=1, j=0; i <= 12 ; i++, j=j+5))
do
echo -n "$j,"
done
No GNU e em alguns outros sistemas, para este problema específico, use seq :
seq -s, 0 5 55
Isso dá a sequência de 0 a 55 (inclusive), separados por uma vírgula.
Existem algumas opções de pure-bash, que podem ser úteis se o seu problema for um pouco mais complicado do que o exemplo sugere. O mais padrão é usar um teste explícito para saber se você está na última iteração:
for ((i=1, j=0; i <= 12 ; i++, j=j+5))
do
echo -n "$j"
[ $i -lt 12 ] && echo -n ,
done
Aqui, imprimimos somente o $j todas as vezes e testamos se $i é menor que 12 (ou seja, não estamos na última iteração) antes de imprimir a vírgula.
Uma alternativa é construir toda a saída como uma única string:
for ((i=1, j=0; i <= 12 ; i++, j=j+5))
do
ACCUM="$ACCUM$j,"
done
echo "${ACCUM%,}"
Aqui, fazemos ACCUM manter a mesma coisa que você já imprimiu, mas não produzimos nada no próprio loop. Você pode cortar a vírgula no final com ${ACCUM%,} : que se expande para o valor de ACCUM com qualquer coisa no final correspondendo , cortado.
Se a opção seq funcionar para o seu caso de uso, eu usaria isso.
Em vez de adicionar vírgulas em todos os lugares e, em seguida, remover o último, aqui está uma possível solução 'pure bash' usando a variável IFS com a forma [*] de expansão de matriz
a=( {0..55..5} ); (IFS=, ; printf '%s\n' "${a[*]}")
0,5,10,15,20,25,30,35,40,45,50,55
Consulte BashGuide / Arrays para obter detalhes - incluindo uma explicação sobre o uso do subgrupo (...) para preservar o pai / mãe IFS do shell.
Se você não quiser usar a abordagem de matriz, será possível evitar o comando sed externo usando os recursos de substituição de sequência internos do shell, por exemplo (novamente no bash)
printf -v str '%s,' {0..55..5}; printf '%s\n' "${str%,}"
0,5,10,15,20,25,30,35,40,45,50,55
As soluções mais sofisticadas que você recebeu são melhores, mas, por uma questão de integridade, você pode simplesmente remover a vírgula final com sed :
for ((i=1, j=0; i <= 12 ; i++, j=j+5))
do
echo -n "$j,"
done | sed 's/,$//'
Aqui está uma solução compatível com POSIX:
i=-5
until [ $((i=i+5)) -eq 55 ]
do printf ${i},
done && echo $i
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
Como alternativa, você pode manipular o IFS:
set -- $(echo $((i=0)); until (exit $((i-55))); do echo $((i=i+5)); done)
IFS=,
echo "$*"
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
Mas ...
unset IFS
printf %s\n "$@"
###OUTPUT###
0
5
10
15
20
25
30
35
40
45
50
55
Todos os incrementos ainda estão disponíveis em $@ e estão disponíveis individualmente em $1 - ${12} .
E isso é divertido e sem loop:
i= ; eval echo $(IFS=0; printf '${i:+,}$((i=i${i:++5}))%s' $(printf %012d))
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
Com bc e tr :
echo '0;while(a+=5<=55){",";a}'|bc|tr -d \n
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
ou apenas bc e shell ...
printf %s $(echo '0;while(a+=5<=55){",";a}'|bc)
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
Com o GNU dc :
dc -e '[pq]sq0[rdn[,]P5+d55=qrdx]dx'
###OUTPUT###
0,5,10,15,20,25,30,35,40,45,50,55
Eu gosto do último o melhor, mas eu sou um otário para um feio script dc .
Para referência, com zsh :
$ echo ${(j(,)):-{0..55..5}}
0,5,10,15,20,25,30,35,40,45,50,55
Surpreende-me que ninguém tenha mencionado simplesmente escrever um backspace no final:
$ printf "%s" {0..55..5},; printf "\b"
0,5,10,15,20,25,30,35,40,45,50,55
Você simplesmente adiciona um cheque quando chega ao fim:
for ((i=1, j=0; i <= 12 ; i++, j=j+5))
do
if [[ $i -ne 12 ]]
then
echo -n "$j,"
else
echo -n "$j"
fi
done
Tags command-line bash shell