Making decisions can be hard. Sometimes, it is advantageous (and fun) to introduce a little randomness into this process.
Over time, you may find that you have a large number of digital items (e.g., PDF research papers, presentation videos, ebooks) to review. Whatever they are, you may not know where you should direct your attention to next.
It could be nice to let chance guide you, and Bash can help.
Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.
Generating A Random Number From a Range
We assume that you have organized your content into directories. Each directory contains either files or subdirectories. We want to generate a random number in the range of zero to the number of items in the target directory (minus one, since we are starting at zero).
The find
and wc
commands can help us:
find ex_dir -mindepth 1 -maxdepth 1 ! -name '.*' | wc -l
-mindepth 1
ensures that we do not includeex_dir
itself in thefind
output.-maxdepth 1
ensures that we do not recurse into any subdirectories that are present inex_dir
.! -name '.*'
ensures that we do not include any hidden directory items.wc -l
counts the number of lines infind
's output (i.e., it determines the number of items in the target directory).
Next, we use shuf
to generate a random number from our range:
shuf -i 0-"$(( ex_num_of_items - 1 ))" -n 1
"$(( ex_num_of_items - 1 ))"
subtracts one from the number of items.-i 0-"$(( ex_num_of_items - 1 ))"
tellsshuf
to generate a random sorting of numbers from zero to the number of items (minus one).-n 1
tellsshuf
to only output one number.
Randomly Selecting a Directory Item
One way to randomly select a directory item (with replacement) is to add each item returned from our find
command to an indexed array. We can use declare
and mapfile
to achieve this:
declare -a ex_obj_paths
mapfile -t ex_obj_paths < \
<(find ex_dir -mindepth 1 -maxdepth 1 ! -name '.*')
Above, we use process substitution and redirection to use the output of our find
command to populate our ex_obj_paths
indexed array.
We can use the random number we previously generated to select a random object from our array. The random number serves as an array item's index number.
Pulling It All Together
We have the pieces required to select random items from a directory, but it would be nice to pull things together into a command line program that we can run from our GNU/Linux desktop. The idea is to pass the program a directory path and have it output the paths of random directory items (it might be nice to see the associated chosen random numbers, too).
Once you find an interesting object, you can quit the program. After quitting, the last randomly selected item path is placed on the system clipboard, enabling you to pass it along to another program for perusal or consumption.
The following script accomplishes this:
It requires xclip
to modify the system clipboard and has a -o
(--open
) option to automatically use xdg-open
to open the last randomly selected item chosen before quitting the program.
Using the Shell to Create Custom Solutions
On GNU/Linux, there are often pre-made programs available that can accomplish the most esoteric of tasks. However, taking the time to use Bash to create your own solution can be a rewarding and edifying experience.