Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pick random images so the newer ones are more likely to be selected in Linux

Tags:

bash

random

I have a bash script on a headless Linux server that accepts a file name as parameter and displays the provided image fullscreen on a beamer.

Users can upload images to a shared folder. I want a random picture of that folder to be chosen each few seconds and displayed. But not completely random. I want that the newer (according to its creation time) a photo is, the more likely it is shown. So all old images are shown as well, but the newer ones will be displayed more frequently.

Is there any way (using Bash and the standard unix tools) to select a random picture from the folder (there are no nested folders, and all files end with the suffix ".jpg"), and consider their age, so the probability a picture is chosen is higher the newer it is?

It would be best if this probability is not linear: while seconds matter when the picture is only a few seconds or minutes old, there does not need to be a huge difference between a picture that is 2 hours or one that is 2 hours and 15 minutes old.

like image 619
muffel Avatar asked Nov 19 '25 22:11

muffel


1 Answers

This random selects jpg files with files created or modified in the last hour being selected three times as likely and files created or modified in the last six hours selected twice as likely as older files:

{
    find . -name '*.jpg' -mmin -60
    find . -name '*.jpg' -mmin -360
    find . -name '*.jpg'
} | shuf -n1

How it works

shuf -n1 randomly selects one line from the lines it is given on standard input. The find commands provide its standard input. Files modified within the last 60 minutes, -mmin -60, are listed by all three find commands. Those modified within the last 360 minutes, -mmin -360 are listed by two of the three commands. The last find command lists all jpg files. This is what gives the variation in probability.

You may adjust both the number of find commands and the cutoff times to suit your preferences.

Improvement

The above works as long as files do not have newlines in their names. To handle that possibility, use nul-terminated lists:

{
    find . -name '*.jpg' -mmin -60 -print0
    find . -name '*.jpg' -mmin 360 -print0
    find . -name '*.jpg' -print0
} | shuf -z -n1
like image 180
John1024 Avatar answered Nov 22 '25 15:11

John1024