Zufallsdatei aus Ordner UND Unterordnern mit Stapelskript öffnen (Windows 7)

2

Ich möchte eine bat-Datei erhalten, die eine zufällige Datei (mit einer beliebigen Erweiterung) aus einem bestimmten Ordner öffnet, aber auch Dateien in allen Unterordnern in diesem Ordner öffnet. Es gibt eine andere Frage, die in etwa so lautet ( Wie öffne ich eine zufällige Datei in einem Ordner und stelle ein, dass nur Dateien mit den angegebenen Dateinamenerweiterungen geöffnet werden sollen? ) Und das folgende Skript bereitstellt:

@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

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

Dieses Skript öffnet jedoch nur Dateien im Hauptordner und keine aus den Unterordnern. Ich bin sicher, das Update ist einfach, aber ich kann es nicht herausfinden. Hilfe wird sehr geschätzt, danke.

Cesar
quelle

Antworten:

6

Dieser Code öffnet eine Datei nicht nur zufällig an einer beliebigen Stelle in der Ordnerhierarchie, sondern ist auch effizienter als das 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

Standardmäßig sucht das Skript im aktuellen Verzeichnis nach Dateien. Sie können jedoch einen Stammpfad als erstes Argument übergeben und stattdessen dort nach Dateien suchen.

Der Code ist effizienter, wenn nur eine Datei geöffnet wird. Wenn Sie jedoch mehrere Dateien öffnen möchten, zeigt er Verbesserungen, da die Liste nur einmal generiert werden muss. Es ist auch effizienter, FINDSTR die ausgewählte Datei finden zu lassen, anstatt die gesamte Liste zu durchlaufen.

Ich habe den Code so strukturiert, dass es einfach ist, mehrere zufällige Dateien zu öffnen. Unten wähle ich zufällig 25 aus und drucke den Befehl aus, um sie zu öffnen. Entfernen Sie einfach das ECHO, um die Dateien tatsächlich zu öffnen:

@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
dbenham
quelle
Nun, ich hatte dies als die Lösung markiert, aber mir wurde klar, dass das erste Mal, wenn ich das (erste) Skript verwende, tatsächlich eine zufällige Datei aus einem zufälligen Unterordner geöffnet wird, ABER wenn ich es das nächste Mal verwende, werden NUR zufällige Dateien geöffnet gleichen Unterordner. Manchmal wird es in einen anderen zufälligen Ordner verschoben, aber es werden wieder nur Dateien aus diesem Ordner geöffnet. Ziemlich komisch ... Ich nehme an, das ist nicht das beabsichtigte Verhalten?
Cesar
@Cesar - Es hängt davon ab, wie Sie das Skript ausführen. Wenn Sie das Skript jedes Mal über Windows Explorer oder eine Verknüpfung starten, wird dieses Verhalten angezeigt. Wenn Sie das Skript jedoch wiederholt im selben Konsolenfenster ausführen, sind die Ergebnisse gut. Dies ist eine Einschränkung der Funktion% random% in Bezug auf die Art der Aussaat. Eine Erklärung finden Sie unter stackoverflow.com/questions/19694021/… . Insbesondere die Antworten von mir und MC-ND.
Dbenham
Es tut mir leid, ich weiß nicht, wie ich es "wiederholt über dasselbe Konsolenfenster" ausführen soll.
Cesar
@Cesar - Starten Sie die cmd.exe-Konsole: Wählen Sie im Startmenü "Alle Programme", dann "Zubehör" und anschließend "Eingabeaufforderung". CD in den Ordner, in dem sich Ihr Skript befindet, und geben Sie den Namen des Skripts ein. Solange Ihr Skript nicht über den Befehl EXIT verfügt, können Sie ihn wiederholt ausführen. EXIT / B ist OK, aber EXIT beendet die Konsole.
Dbenham
1

Während der Code in der Antwort von dbenham ist, was ich verwenden würde, nur für eine Alternative

@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"

Der Code funktioniert folgendermaßen:

  1. Führt einen rekursiven dirBefehl aus.
  2. Gibt für jede Datei in der Liste den Namen der Datei und eine Zufallszahl aus.
  3. Sortiert die Liste der Dateien. Da ihm eine Zufallszahl vorangestellt ist, ist die Reihenfolge zufällig.
  4. Aus der Liste wird die erste Datei abgerufen.
  5. Der abgerufene Datensatz wird geteilt, wobei die ursprüngliche Zufallszahl verworfen und die ausgewählte Datei gestartet wird.

Und ja, es ist CPU-intensiv, da ein sortBefehl und vier cmdInstanzen gestartet werden , damit es funktioniert .

MC ND
quelle