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.
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
You can use the
--random-source=FILEoption 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.
shufdoesn't accept multiple input files. Use
catfor such cases.
-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
$ printf 'apple\nbanana\ncherry' | shuf -n2 cherry apple
As seen in the example above,
shufwill add a newline character if it is not present for the last input line.
-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
If a limit using
-nis not specified,
shuf -rwill produce output lines indefinitely.
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
-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
2^64 - 1is 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
See unix.stackexchange: generate random strings if numbers aren't enough for you.
-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
-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^@