¿Cómo mostrar números en orden inverso usando seq (1)?

36

He iterado sobre los números en varios orden. Puedo mostrarlos en orden creciente, incluso con pasos como:

$ seq --separator="," 1 10
1,2,3,4,5,6,7,8,9,10
$ seq --separator="," 1 2 10
1,3,5,7,9

También puedo mostrarlos en orden inverso, ni continuo ni paso a paso.

$ seq --separator="," 10 1   
$ seq --separator="," 10 2 1

No hay salida para los comandos anteriores.

Los detalles de mi caparazón:

$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

Avíseme cómo podría mostrar los números en orden descendente.

mtk
fuente
10
Para futuros lectores, seqes una herramienta completamente no estándar y no hay garantía de que ninguna de las dos implementaciones sea la misma. Si necesita escribir un bucle que itera hacia atrás sobre los números en bash, use for ((i=$max;i>=0;i--)) …o similares.
kojiro

Respuestas:

50

usar incremento negativo

seq -s, 10 -2 1
10,8,6,4,2
watael
fuente
20

En general, usted no desea utilizar seq, no es portátil (incluso entre los entornos estándar de Linux). Si estás usando ksh, zsh, o bash4 +, puede utilizar la expansión de llaves:

echo {10..1..2} | tr " " ,
10,8,6,4,2
Chris Down
fuente
1
Eso es corto y rápido, pero estoy en la versión anterior de fiesta.
MTK
20
Dulce respuesta, pero hay algo de ironía cuando señalas que no seqes estándar y luego usas la expansión de llaves solo bash-4. ;)
kojiro
@kojiro - Ningún argumento para ser honesto ;-) Mi principal preocupación no es uno de si existe o no la orden (que puede o no importa en función de si se está distribuyendo el script / etc), pero si se ejecuta el comando como se espera el autor. la expansión de llaves de bash4 casi tiene que garantizarse (si funciona, funciona como se espera), mientras que seqno lo hace.
Chris abajo
1
¿Por qué no es portátil? ¿Tienes fuentes o pruebas? Estoy interesado.
Benoit Duffez
15

Otra forma en puro bash, ksh o zsh:

for ((i=10;i>0;i-=2)) ; do echo -n "$i," ; done

Una manera pura de POSIX sh:

i=10
while [ "$i" -gt 2 ]; do printf "$i,"; i=$((i-2)); done
echo "$i"
prisa
fuente
1
forLa segunda expresión debería ser la prueba y la tercera el paso.
manatwork
7

Ahora, los POSIX estándar:

awk 'BEGIN{for (i = 10; i > 0; i -= 2) print i}' | paste -sd , -

(Curiosamente, con mawk(y en menor medida gawktambién) mucho más rápido que GNU seqen i = 10000000lugar de i = 10)

O

i=10; set --
while [ "$i" -gt 0 ]; do
  set -- "$@" "$i"
  i=$(($i - 2))
done
IFS=,
echo "$*"

(solo sería más eficiente con un pequeño número de iteraciones, especialmente con bash)

O

echo 'for(i=10;i>0;i-=2) i' | bc | paste -sd , -

(lo que admitiría números de cualquier tamaño, pero tenga en cuenta que más allá de un cierto número de dígitos (números mayores que 10 70 en la ubicación POSIX al menos), las líneas se incluirán con barras invertidas)

Stéphane Chazelas
fuente
1
En GNU bc, puede evitar el ajuste de línea configurando BC_LINE_LENGTH=0el entorno. No hay tanta suerte en otras implementaciones.
Gilles 'SO- deja de ser malvado'
1
¿Por qué usar los argumentos posicionales en lugar de recorrer s=$s,$io llamar echo -n/ echo \c/ printf?
Gilles 'SO- deja de ser malvado'
2

Puede invertir el orden usando tac(cat in reverse). Incluso si seqse comportara de manera diferente en varios sistemas, creo que lo siguiente debería ser lo más portátil posible:

$ seq 1 10 | tr '\012' ',' | sed 's/,$//'; echo
1,2,3,4,5,6,7,8,9,10
$ seq 1 10 | tac | tr '\012' ',' | sed 's/,$//'; echo
10,9,8,7,6,5,4,3,2,1
$
hlovdal
fuente
2

Probar con:

   seq [OPTION]... FIRST INCREMENT LAST

Ejemplo:

$ seq 10 -1 1

jluna
fuente