3

I have written a little bash script that reads commands (one per line), in a text file. At the moment, the script (shown below), is executing the commands in a sequential order (i.e. in the same order entered in the file).

I would like help to modify the script below, so that it reads the commands into an array, then randomizes that array (i.e. list) before iterating though the randomized list.

This is what I have so far:

while read -r -a array
do
   python make_move.py "${array[@]}"
done < game_commands.dat

I am running bash 4.1.5 on Ubuntu 10.0.4 LTS

[[Edit]]

I need to execute ALL of the commands in the list, with each command being executed ONLY ONCE.

Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
  • This is a FAQ; see http://mywiki.wooledge.org/BashFAQ/026 and also e.g. http://stackoverflow.com/questions/886237/how-can-i-randomize-the-lines-in-a-file-using-a-standard-tools-on-redhat-linux – tripleee Oct 12 '11 at 16:08
  • @tripleee: in the end it was the shuffle command in the link you posted that provided the solution. Do you want to post that as an answer so I can accept it? – Homunculus Reticulli Oct 12 '11 at 17:36
  • `$array` is not actually an array. The loop is iterating over the lines output by `shuf` (as in Sven's answer) individually. Regardless, the effect will be as requested, but the first line should really be: `while read -r line` and the third line should be `python make_move.py "$line"`. If you really needed the lines in an array, you could still do that, but your Python script might not handle it correctly. – Dennis Williamson Oct 28 '11 at 17:51

3 Answers3

4

You can shuffle the lines of a file using the shuf command.

Edit: Your code using shuf would look

while read -r -a array
do
    python make_move.py "${array[@]}"
done < <(shuf game_commands.dat)
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • How do I use **shuf** in my script?. My first attempt was this: a=shuf $cmds where _cmds_ was the array read from file, and I got the error: "GET_SWORD: command not found". GET_SWORD happens to be the first command in the command array. So basically, I want to shuffle an array and get a new shuffled array which I can then iterate over. – Homunculus Reticulli Oct 12 '11 at 17:20
1

If you need to execute something like this on a system where shuf is not available, (bash 4 only, easily adaptable for most modern shells):

unset max s i
readarray -t _cmd < game_commands.dat
while (( max < ${#_cmd[@]} )); do
  (( i = RANDOM % ${#_cmd[@]} ))
  [[ $s == *,$i,*  ]] || {
     python make_move.py "${_cmd[i]}"
         (( max++ ))
        }
  s+=,$i,
done
Dimitre Radoulov
  • 27,252
  • 4
  • 40
  • 48
0

Try sort -R. That will shuffle the lines randomly. EDIT: But the same lines will always appear in blocks...

Tomas
  • 57,621
  • 49
  • 238
  • 373
  • This won't shuffle all lines, it will sort by a random hash. This means that equal lines will always appear in blocks. – Sven Marnach Oct 12 '11 at 15:15