How to randomize the output from seq?
You can just pipe the output to shuf
.
$ seq 100 | shuf
Example
$ seq 10 | shuf
2
6
4
8
1
3
10
7
9
5
If you want the output to be horizontal then pipe it to paste
.
$ seq 10 | shuf | paste - -s -d ' '
1 6 9 3 8 4 10 7 2 5
$ seq 10 | shuf | paste - -s -d ' '
7 4 6 1 8 3 10 5 9 2
$ seq 10 | shuf | paste - -s -d ' '
9 8 3 6 1 2 10 4 7 5
Want it with commas in between? Change the delimiter to paste
:
$ seq 10 | shuf | paste - -s -d ','
2,4,9,1,8,7,3,5,10,6
Is there a simpler way to randomize the items in an array with a single command?
Assuming you have an array of decimal integers:
arr=(4 8 14 18 24 29 32 37 42)
You could use printf
and shuf
to randomize the elements of the array:
$ arr=($(printf "%d\n" "${arr[@]}" | shuf))
$ echo "${arr[@]}"
4 37 32 14 24 8 29 42 18
(the above assumes you've not modified $IFS
).
If all that you need is random numbers between two integers, say 10
and 20
, you do not need any extra processes other than shuf
by using the -i
option:
$ shuf -i 10-20
12
10
20
14
16
19
13
11
18
17
15
Quoting from man shuf
:
-i, --input-range=LO-HI
treat each number LO through HI as an input line
printf '%s, ' `seq 1 10 | shuf`
You don't even need a for
loop.
OUTPUT
7, 3, 4, 10, 2, 9, 1, 8, 5, 6,
To get them in a shell array you do:
( set -- $(seq 1 10 | shuf) ; printf '%s, ' "$@" )
OUTPUT
5, 9, 7, 2, 4, 3, 6, 1, 10, 8,
And then they're in your shell array.
If you get them in the shell array, you don't even need printf
:
( set -- $(seq 1 10 | shuf); IFS=, ; echo "$*" )
OUTPUT
9,4,10,3,1,2,7,5,6,8
By the way, seq
and printf
are kinda made for each other. For instance if I want to repeat a string 1000 times?
printf 'a string\n%.0b' `seq 1 1000`
OUTPUT
a string
... 999 a string
lines later...
a string
Or...
printf 'a string,%.0b' `seq 1 10`
OUTPUT
a string,a string,a string,a string,a string,a string,a string,a string,a string,a string,
I want to execute a command 39 times?
printf 'echo "run %d"\n' `seq 1 39` | . /dev/stdin
OUTPUT
run 1
... 38 run
lines later ...
run 39