I would probably look to do this in another language that has some better handling for situations like this if possible. For example, in python
you could do it like
files = os.listdir('.')
random.shuffle(files)
for path in files:
# do your code test stuff on path
Having a function that will return the next file name is tougher to do in bash
, but if you just want to operate on the files in a random order we can follow @shelter's recommendation and use arrays, combined with a randomizing function found in this answer. Here we will shuffle all the filenames in an array, then iterate over them:
shuffle() {
local i tmp size max rand
# $RANDOM % (i+1) is biased because of the limited range of $RANDOM
# Compensate by using a range which is a multiple of the array size.
size=${#array[*]}
max=$(( 32768 / size * size ))
for ((i=size-1; i>0; i--)); do
while (( (rand=$RANDOM) >= max )); do :; done
rand=$(( rand % (i+1) ))
tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
done
}
array=( * )
shuffle
for((i=0; i<${#array[*]}; i++ )); do
printf "Operating on %s\n" "${array[i]}"
# do whatever test makes sense on "${array[i]}"
done
if you really want a function that will return the "next" file we could do it a bit differently from above, setting a variable that we'll use as holding our current filename. So we ill replace the for loop at the bottom with another function definition and loop like so:
next_file() {
if [[ "$array_ind" -ge "${#array[*]}" ]]; then
cur=""
else
cur="${array[array_ind++]}"
fi
}
array_ind=0
# now we use next_file whenever we want `cur` to get the next file:
next_file
while [[ ! -z "$cur" ]]; do
printf -- "--%s--\n" "$cur"
next_file
done