shuf

The shuf command helps you randomize input lines. And there are features to limit the number of output lines, repeat lines and even generate random positive integers.

Randomize input lines

By default, shuf will randomize the order of input lines. Here's an example:

$ cat purchases.txt 
coffee
tea
washing powder
coffee
toothpaste
tea
soap
tea

$ shuf purchases.txt
tea
coffee
tea
toothpaste
soap
coffee
washing powder
tea

info You can use the --random-source=FILE option to provide your own source for randomness. With this option, the output will be the same across multiple runs. See Sources of random data for more details.

warning shuf doesn't accept multiple input files. Use cat for such cases.

Limit output lines

Use the -n option to limit the number of lines you want in the output. If the value is greater than the number of lines in the input, it would be similar to not using the -n option.

$ printf 'apple\nbanana\ncherry' | shuf -n2
cherry
apple

info As seen in the example above, shuf will add a newline character if it is not present for the last input line.

Repeated lines

The -r option helps if you want to allow input lines to be repeated. This option is usually paired with -n to limit the number of lines in the output.

$ cat fruits.txt
banana
papaya
mango

$ shuf -n3 -r fruits.txt
banana
mango
banana

$ shuf -n5 -r fruits.txt
papaya
banana
mango
papaya
papaya

info If a limit using -n is not specified, shuf -r will produce output lines indefinitely.

Specify input as arguments

You can use the -e option to specify multiple input lines as arguments to the command.

# quote the arguments as necessary
$ shuf -e hi there 'hello world' good
hello world
good
hi
there

$ shuf -n1 -e red green blue
blue

$ shuf -n4 -r -e red green blue
blue
green
red
blue

The shell will autocomplete unquoted glob patterns (provided there are files that match the given expression). You can thus easily construct a solution to get a random selection of files matching the given glob pattern.

$ echo *.csv
marks.csv mixed_fields.csv report_1.csv report_2.csv scores.csv

$ shuf -n2 -e *.csv
scores.csv
marks.csv

Generate random numbers

The -i option will help you generate random positive integers.

$ shuf -i 5-8
5
8
7
6

$ shuf -n3 -i 100-200
170
112
148

$ shuf -n5 -r -i 0-1
1
0
0
1
1

info 2^64 - 1 is the maximum allowed integer when I tested it on my machine.

$ shuf -i 18446744073709551612-18446744073709551615
18446744073709551615
18446744073709551614
18446744073709551612
18446744073709551613

$ shuf -i 18446744073709551612-18446744073709551616
shuf: invalid input range: ‘18446744073709551616’:
Value too large for defined data type

# seq can help in such cases, but remember that shuf needs to read entire input
$ seq 100000000000000000000000000000 100000000000000000000000000105 | shuf -n2
100000000000000000000000000039
100000000000000000000000000018

seq can also help when you need negative and floating-point numbers.

$ seq -10 -8 | shuf
-9
-10
-8

$ seq -f'%.4f' 100 0.25 3000 | shuf -n3
1627.7500
1303.5000
2466.2500

info See unix.stackexchange: generate random strings if numbers aren't enough for you.

Specifying output file

The -o option can be used to specify the output file to be used for saving the results. You can use this for in-place editing as well, since shuf reads the entire input before opening the output file.

$ shuf nums.txt -o rand_nums.txt

$ cat rand_nums.txt
42
1000
3.14

NUL separator

Use -z option if you want to use NUL character as the line separator. In this scenario, shuf will ensure to add a final NUL character even if not present in the input.

$ printf 'apple\0banana\0cherry' | shuf -z -n2 | cat -v
cherry^@banana^@