List X random files from a directory

Try piping the ls output to shuf, e.g.

$ touch 1 2 3 4 5 6 7 8 9 0
$ ls | shuf -n 5
5
9
0 
8
1

The -n flag specifies how many random files you want.


Since you're mentioning zsh:

rand() REPLY=$RANDOM
print -rl -- *(o+rand[1,30])

You can replace print with say ogg123 and * with say **/*.ogg


It's quite easy to solve this with a tiny bit of Perl. Select four files at random from the current directory:

perl -MList::Util=shuffle -e 'print shuffle(`ls`)' | head -n 4

For production use though, I would go with an expanded script that doesn't rely on ls output, can accept any dir, checks your args, etc. Note that the random selection itself is still only a couple of lines.

#!/usr/bin/perl    
use strict;
use warnings;
use List::Util qw( shuffle );

if ( @ARGV < 2 ) {
    die "$0 - List n random files from a directory\n"
        . "Usage: perl $0 n dir\n";
}
my $n_random = shift;
my $dir_name = shift;
opendir(my $dh, $dir_name) || die "Can't open directory $dir_name: $!";

# Read in the filenames in the directory, skipping '.' and '..'
my @filenames = grep { !/^[.]{1,2}$/ } readdir($dh);
closedir $dh;

# Handle over-specified input
if ( $n_random > $#filenames ) {
    print "WARNING: More values requested ($n_random) than available files ("
          . @filenames . ") - truncating list\n";
    $n_random = @filenames;
}

# Randomise, extract and print the chosen filenames
foreach my $selected ( (shuffle(@filenames))[0..$n_random-1] ) {
    print "$selected\n";
}

Tags:

Shell

Zsh

Files