Windows – Opening random file from folder AND subfolders with batch script (Windows 7)

batch fileopenwindows 7

I want to get a bat file that will open a random file (with any extension) from a specific folder, but also open files in all subfolders within that folder. There's another question that asked something like this (How do I open a random file in a folder, and set that only files with the specified filename extension(s) should be opened?), and provided this script:

@echo off & setlocal
 :: start of main
 rem Set your path here:
 set "workDir=C:\DVDCOVERS"

 rem Read the %random%, two times is'nt a mistake! Why? Ask Bill.
 rem In fact at the first time %random% is nearly the same.
 @set /a "rdm=%random%"
 set /a "rdm=%random%"

 rem Push to your path.
 pushd "%workDir%"

 rem Count all files in your path. (dir with /b shows only the filenames)
 set /a "counter=0"
 for /f "delims=" %%i in ('dir /b ^|find "."') do call :sub1

 rem This function gives a value from 1 to upper bound of files
 set /a "rdNum=(%rdm%*%counter%/32767)+1"

 rem Start a random file
 set /a "counter=0"
 for /f "delims=" %%i in ('dir /b ^|find "."') do set "fileName=%%i" &call :sub2

 rem Pop back from your path.
 popd "%workDir%"

 goto :eof
 :: end of main

 :: start of sub1
 :sub1
 rem For each found file set counter + 1.
 set /a "counter+=1"
 goto :eof
 :: end of sub1

 :: start of sub2
 :sub2
 rem 1st: count again,
 rem 2nd: if counted number equals random number then start the file.
 set /a "counter+=1"
 if %counter%==%rdNum% (start "" "%fileName%")
 goto :eof
 :: end of sub2

 :: -snap--- end of batch

Source: http://forums.majorgeeks.com/showthread.php?t=181574

However, this script only opens files located in the main folder and none from the subfolders. I'm sure the fix is a simple one but I can't figure it out. Help is much appreciated, thanks.

Best Answer

Not only does this code randomly open a file anywhere within the folder hierarchy, it is also more efficient than the original:

@echo off
setlocal

:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"

:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N

call :openRandomFile

:: Delete the temp file
del "%tempFile%"

exit /b

:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
  'findstr "^%randomNum%:" "%tempFile%"'
) do start "" "%%B"
exit /b

By default the script will look for files under the current directory, but you can pass a root path as the first argument, and it will start looking there instead.

The code is more efficient when opening just one file, but it really shows improvement if you want to open multiple files, since it only needs to generate the list once. It is also more efficient to let FINDSTR find the selected file instead of looping through the entire list.

I structured the code to make it easy to open multiple random files. Below I randomly select 25, and print out the command to open them. Simply remove the ECHO to actually open the files:

@echo off
setlocal

:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"

:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N

:: Open 25 random files
for /l %%N in (1 1 25) do call :openRandomFile

:: Delete the temp file
del "%tempFile%"

exit /b

:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
  'findstr "^%randomNum%:" "%tempFile%"'
) do echo start "" "%%B"
exit /b
Related Question