Page 1 of 3 123 LastLast
Results 1 to 10 of 25

Thread: Random File

  1. #1
    Join Date
    Aug 2006
    Location
    Chicago, IL, USA
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Random File

    I'm trying to figure out how to pick a random file in bash. So for example, I use 'ls' to generate a list of all the files in the current directory. I then want to be able to pipe (|) it to a "random" command that will return the name of one of the files chosen randomly. I know you can generate a random number with bash. So I assume the way to go about this would be to put the output of ls in an array and then generate a random number based on the length of the array. And then use that random number to return a random filename.

    That might be totally wrong (I'm basing that solely on prior knowledge of other languages). I'm just interested in an easy way to go about this.

  2. #2
    Join Date
    Feb 2007
    Beans
    2,729

    Re: Random File

    That sounds like a perfectly good way to solve the problem.

    No need to pipe - just pick a random number.

    Here's a nice trick - see if you can figure out what is going on. Change directories into the directory you want to select random files, and then run:

    Code:
    set -- *
    echo ${3}
    MrC

  3. #3
    Join Date
    Aug 2006
    Location
    Chicago, IL, USA
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Re: Random File

    Thanks a lot! That worked perfect. But I'm having a hard time figuring out what it means. Here is what I found about the set -- part:

    If no arguments follow this option, then the positional parameters are unset.
    Otherwise, the positional parameters are set to the arguments,
    even if some of them begin with a `-'.

    But I still don't get how it chooses a random file. I know * is a wildcard and that set is normally used to set variables.

  4. #4
    Join Date
    Feb 2007
    Beans
    2,729

    Re: Random File

    The * in this context is a file pattern maching wildcard. It matches every file (not including dot files like .bashrc).

    The statements I gave do not choose a random file; they showed you how to setup the array, and how to access the nth cell.

    Search man bash for random. Then search for Arithmetic Expansion and ARITHMETIC EVALUATION.

    MrC

  5. #5
    Join Date
    Apr 2007
    Beans
    88

    Re: Random File

    Your original post was phrased in a way that suggested that you didn't want the code written for you but just wanted some hints on how to do it yourself.

    Your analysis of the problem was spot-on...

    1. put the output of 'ls' in an array
    2. then generate a random number based on the length of the array
    3. and then use that random number to return a random filename.


    Mr. C. helped you with the first of these problems by showing you a nifty one-liner that fills an array without the bother of looping through the output of 'ls' and assigning each filename to the array individually. To understand it remember that before the builtin command 'set' is evoked, the shell has to parse the line "set -- *". When the shell sees the asterisk it expands it into a string of all the files in the current directory. Then 'set' is evoked and given the option '--' and the string of arguments, so it sets the positional parameters (from $1 upwards) to those filenames.

    Anyway, now you have to solve items 2 and 3 in your list - generate a random number within a set range, and use that number to return a random filename from the array.

    Here's a trick to help you with the 3rd problem...
    Assuming that in stage two you've assigned your random number to the variable 'random_num', try...
    Code:
    echo ${!random_num}
    The '!' has a special significance here.

  6. #6
    Join Date
    Feb 2007
    Beans
    2,729

    Re: Random File

    Quote Originally Posted by jyba View Post
    Assuming that in stage two you've assigned your random number to the variable 'random_num', try...
    Code:
    echo ${!random_num}
    The '!' has a special significance here.
    ... assuming the random number has been properly scaled to fit. Good technique.

    MrC

  7. #7
    Join Date
    Apr 2007
    Beans
    88

    Re: Random File

    Yes, but I think it's for Cheater to figure out how to turn some huge random number into a number within the range of '1' to 'the number of files'. His statement 'generate a random number based on the length of the array' suggests he's most of the way there.

  8. #8
    Join Date
    Feb 2007
    Beans
    2,729

    Re: Random File

    We're in complete agreement. My clarification was aimed towards mollifying the frustration at running your variable expansion and having nothing returned. Examples, in my opinion, should produce results, not blank lines, which leads to confusion.

    MrC

  9. #9
    Join Date
    Apr 2007
    Beans
    88

    Re: Random File

    Okay, agreed; at risk of confusing matters...
    Code:
    set -- "elephant" "tiger" "penguin" "kangaroo"
    number=3
    echo ${number}          #  Echo's "3"
    echo ${!number}         #  Why does this echo "penguin"?
    Anyway, you've sorted problem one, I've sorted problem three. Over to Cheater...
    Last edited by jyba; July 16th, 2007 at 07:45 PM.

  10. #10
    Join Date
    Aug 2006
    Location
    Chicago, IL, USA
    Beans
    Hidden!
    Distro
    Ubuntu Development Release

    Re: Random File

    Thanks a lot for all of your help. I've really learned a lot about bash.

    For anyone wondering, here is the final script I came up with

    Code:
    set -- *
    length=$#
    random_num=$(( $RANDOM % ($length + 1) ))
    echo ${!random_num}

Page 1 of 3 123 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •