Reputation: 7928
I would like to write a simple bash script that randomly selects a .flac
file from the /music/
folder (it will have to be recursive because there are many subfolders within that folder), and copy that file to /test/random.flac
This post is very close to what I want to do but I'm not sure how to change the script to do what I want.
I tried this:
ls /music |sort -R |tail -1 |while read file; do
cp $file /test/random.flac
done
But I'm missing how to tell ls
to do a recursive search of all the .flac
inside the subfolders.
Upvotes: 0
Views: 1164
Reputation: 52132
You can shove all the files into an array, then select one at a random index to move. This requires the globstar
option to be enabled so you can use the **/*
glob pattern:
shopt -s globstar
flacfiles=(/music/**/*.flac)
cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac
To select a random index, we take $RANDOM
modulo the number of elements in the flacfiles
array.
If you want an error message in case the glob doesn't match anything, you can use the failglob
shell option:
shopt -s globstar failglob
if flacfiles=(/music/**/*.flac); then
cp "${flacfiles[RANDOM % ${#flacfiles[@]}]}" /test/random.flac
fi
This fails with an error message
-bash: no match: music/**/*.flac
in case there are no matching files and doesn't try to copy anything.
If you know for sure that there are .flac
files, you can ignore this.
Upvotes: 3
Reputation: 27215
Use find
instead of ls
:
find /music/ -iname '*.flac' -print0 | shuf -z -n1
The find
part will find all flac files inside the directory /music/
and list them.
shuf
shuffles that list and prints the first entry (which is random, because the list was shuffled).
-print0
and -z
are there to use \NUL
for separating the file names. Without these options, \n
(newline) would be used, which is unsafe, because filenames can contain newlines (even though it is very uncommon).
If you want to copy just one random file, there's no need for a while
loop. Use Substitution $()
instead.
cp "$(find /music/ -iname '*.flac' -print0 | shuf -z -n1)" /test/random.flac
Upvotes: 3