Abrindo arquivo aleatório da pasta E subpastas com script em lote (Windows 7)

1

Eu quero obter um arquivo bat que abra um arquivo aleatório (com qualquer extensão) de uma pasta específica, mas também abra arquivos em todas as subpastas dessa pasta. Há outra pergunta que perguntou algo assim (), e desde que 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

Fonte: link

No entanto, esse script só abre arquivos localizados na pasta principal e nenhum das subpastas. Tenho certeza que a correção é simples, mas não consigo entender. A ajuda é muito apreciada, obrigado.

    
por Cesar 31.01.2015 / 18:37

2 respostas

4

Esse código não apenas abre aleatoriamente um arquivo em qualquer lugar dentro da hierarquia de pastas, como também é mais eficiente que o 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

Por padrão, o script procurará arquivos no diretório atual, mas você pode passar um caminho raiz como o primeiro argumento e começará a procurar lá.

O código é mais eficiente ao abrir apenas um arquivo, mas ele realmente mostra melhorias se você deseja abrir vários arquivos, pois ele só precisa gerar a lista uma vez. Também é mais eficiente deixar o FINDSTR localizar o arquivo selecionado em vez de percorrer toda a lista.

Eu estruturei o código para facilitar a abertura de vários arquivos aleatórios. Abaixo, seleciono aleatoriamente 25 e imprimo o comando para abri-los. Simplesmente remova o ECHO para realmente abrir os arquivos:

@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
    
por 01.02.2015 / 00:32
1

Enquanto o código na resposta de dbenham é o que eu usaria, apenas por uma alternativa

@echo off
    setlocal enableextensions disabledelayedexpansion

    set "rootFolder=C:\DVDCOVERS" 

    for /f "usebackq tokens=1,* delims=:" %%a in ('
        cmd /q /v /e /c "for /f delims^= %%a in ('dir /a-d /s /b "%rootFolder%"') do echo(!random!:%%a"
        ^| sort 2^>nul
        ^| cmd /q /e /v /c "set /p ".^=" & echo(!.!"
    ') do start "" "%%~b"

O código funciona da seguinte maneira:

  1. Executa um comando dir recursivo.
  2. Para cada arquivo na lista, ecoa o nome do arquivo e um número aleatório.
  3. Classifica a lista de arquivos. Como é prefixado com um número aleatório, a ordem é aleatória.
  4. Na lista, o primeiro arquivo é recuperado.
  5. O registro recuperado é dividido, descartando o número aleatório inicial e iniciando o arquivo selecionado.

E, sim, é um uso intensivo da CPU, pois, para funcionar, um comando sort e quatro cmd instâncias são iniciadas.

    
por 02.02.2015 / 08:43