Come visualizzare i numeri in ordine inverso usando seq (1)?


36

Ho ripetuto i numeri in ordine diverso. Sono in grado di visualizzarli in ordine crescente, anche con passaggi come:

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

Sono anche in grado di visualizzarli in ordine inverso, né continuo né graduale.

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

Nessun output per i comandi precedenti.

I dettagli della mia shell:

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

Fammi sapere come sarei in grado di visualizzare i numeri in ordine decrescente?


10
Per i futuri lettori, seqè uno strumento completamente non standard e non vi è alcuna garanzia che due implementazioni saranno le stesse. Se devi scrivere un ciclo che scorre indietro sui numeri in bash, usa for ((i=$max;i>=0;i--)) …o simili.
Kojiro,

Risposte:


50

usa l'incremento negativo

seq -s, 10 -2 1
10,8,6,4,2

20

In generale, non si desidera utilizzare seq, non è portatile (anche tra ambienti Linux standard). Se stai usando ksh, zsh o bash4 +, puoi usare l'espansione del controvento:

echo {10..1..2} | tr " " ,
10,8,6,4,2

1
È breve e veloce, ma sono nella versione bash precedente.
mtk,

20
Risposta dolce, ma c'è un po 'di ironia quando si sottolinea che seqnon è standard e quindi si usa l'espansione di parentesi solo bash-4. ;)
kojiro,

@kojiro - Nessun argomento a dire il vero ;-) La mia principale preoccupazione non è se il comando esiste (ciò può o meno dipendere dal fatto che lo script sia distribuito / ecc.), ma se il comando viene eseguito come previsto da l'autore. L'espansione del rinforzo di bash4 ha quasi quello garantito (se funziona, funziona come previsto), mentre seqnon lo fa.
Chris Down,

1
Perché non è portatile? Hai fonti o prove? Sono interessato.
Benoit Duffez,

15

Un altro modo in puro bash, ksh o zsh:

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

Un modo POSIX puro:

i=10
while [ "$i" -gt 2 ]; do printf "$i,"; i=$((i-2)); done
echo "$i"

1
forLa seconda espressione dovrebbe essere il test e la terza il passo.
arte

7

Ora, quelli POSIX standard:

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

(interessante, con mawk(e anche in misura minore gawk) molto più veloce di GNU seqper i = 10000000anziché i = 10)

O

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

(sarebbe più efficiente solo con un numero limitato di iterazioni, specialmente con bash)

O

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

(che supporterebbe numeri di qualsiasi dimensione, ma nota che oltre un certo numero di cifre (almeno un numero maggiore di 10 70 nella locale POSIX), le linee verrebbero racchiuse da barre rovesciate)


1
In GNU bc, è possibile evitare il ritorno a capo impostando BC_LINE_LENGTH=0nell'ambiente. Nessuna fortuna su altre implementazioni.
Gilles 'SO- smetti di essere malvagio' il

1
Perché usare gli argomenti posizionali piuttosto che fare un giro s=$s,$io chiamare echo -n/ echo \c/ printf?
Gilles 'SO- smetti di essere malvagio' il

2

Puoi invertire l'ordine usando tac(cat in reverse). Anche se seqdovrebbe comportarsi in modo diverso su vari sistemi, penso che quanto segue dovrebbe essere il più portatile possibile:

$ 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
$

2

Prova con:

   seq [OPTION]... FIRST INCREMENT LAST

Esempio:

$ seq 10 -1 1

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.