cmd-Batch: neuste Datei einer Dateimenge exkl. einer Untermenge daraus?
Hallo
Gegeben ist ein bestimmtes Verzeichnis unbekannter Grösse mit wav- und anderen Dateien. Weiter ist gegeben ein Datenfeld (Array) bekannter Grösse mit lauter wav-Dateien aus jenem Verzeichnis (Untermenge). Aus dem Verzeichnis abzüglich der Untermenge (Array) soll dann die neuste Datei gezogen werden.
Wie könnte ein cmd-Batch dazu aussehen?
Vielen Dank. Grüsse, Louis
Ich habe meine Anforderung nun anders lösen können. Darum brauche ich für die obige Idee keinen Batch mehr.
Grüsse, Louis
1 Antwort
@echo off
chcp 65001 >nul
rem erzeuge Array mit dem verglichen werden soll.
rem ermittle alle .wav-Dateien nach Erzeugungsdatum sortiert die Neueste zuerst!
for /f "tokens=1* delims=[]" %%a in ('dir /tc /o-d /b "*.wav" ^| find /v /n ""') do (
set "WavArray.%%a=%%b"
)
:check
echo Drücke eine beliebige Taste um zu prüfen ob eine neue .wav im Verzeichnis ist.
pause>nul
rem ebenfalls wie oben sortiert einlesen
for /f "tokens=*" %%a in ('dir /tc /o-d /b "*.wav"') do (
rem im ersten Element ist des Arrays ist die Datei gespeichert, welche zuletzt erzeugt wurde (so gott will)
if "%WavArray.1%" neq "%%a" (
echo "%%a" ist die neuste hinzugekommene .wav-Datei!
rem fertig es gibt keien Grund für weitere Prüfungen
goto :break
) else (
echo keine neue Datei
goto :check
)
)
:break
pause
...allerding wäre in diesem Fall das Array Unsinn (wir brachen ja nur die jeweils neuste Datei):
@echo off
chcp 65001 >nul
for /f "tokens=*" %%a in ('dir /tc /o-d /b "*.wav"') do (
set "NewestWav=%%a"
goto :break
)
:break
:check
echo Drücke eine beliebige Taste um zu prüfen ob eine neue .wav im Verzeichnis ist.
pause>nul
for /f "tokens=*" %%a in ('dir /tc /o-d /b "*.wav"') do (
if "%NewestWav%" neq "%%a" (
echo "%%a" ist die neuste hinzugekommene .wav-Datei!
goto :break
) else (
echo keine neue .wav-Datei
goto :check
)
)
:break
pause
ich wäre zu gespannt wie Du die Sache gelöst hat...
warum willst du die Liste der Dateinamen durchackern?
Es genügt doch völlig zu prüfen das die neue Zufallszahl nicht die gleiche ist wie die letzte:
@echo off
chcp 65001 >nul
for /f "tokens=1* delims=[]" %%a in ('dir /s /b "c:/windows\Media\*.wav" ^|find /v /n ""') do (
set "myWavArray.%%a=%%b"
set "myWavArray.Count=%%a"
)
if "myWavArray.Count"=="" (
echo Keine wav!
pause
exit /b
)
rem es kann nie 2 mal die gleiche Zahl gezogen werden (außer es gibt nur eine Datei)
call :getNextRandom MyNumber %myWavArray.Count%
echo %MyNumber%
call echo "%%myWavArray.%MyNumber%%%"
rem nächste...
call :getNextRandom MyNumber %myWavArray.Count%
echo %MyNumber%
call echo "%%myWavArray.%MyNumber%%%"
call :getNextRandom MyNumber %myWavArray.Count%
echo %MyNumber%
call echo "%%myWavArray.%MyNumber%%%"
pause
exit /b
:::: Subroutines :::
rem ermittle eine Zufallszahl, welche nicht mit der letzten übereinstimmt
:getNextRandom %1=VariablenName %2=höchste Zufallszahl
if "%~2"=="1" (
set "%~1=1"
exit /b 1
)
set /a "getNextRandom.NewRandomNumber=%random% %% %~2 +1"
if "%getNextRandom.LastRandomNumber%"=="%getNextRandom.NewRandomNumber%" (
goto :getNextRandom
)
set "getNextRandom.LastRandomNumber=%getNextRandom.NewRandomNumber%"
set "%~1=%getNextRandom.NewRandomNumber%"
exit /b 0
Oder du prüfst ob alle bisher gezogenen Zahlen schon mal da waren und fängst erst vom neuen an, wenn du alle durch hast:
@echo off
chcp 65001 >nul
set "maxNumber=5"
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
echo:
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
echo:
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
call :GetUniqueRandom MeineVariable %maxNumber%
echo %MeineVariable%
pause
exit /b
:::: Subroutines :::
:GetUniqueRandom %1=VariablenName %2=höchste Zufallszahl
if "%~2"=="1" (
set "%~1=1"
exit /b 1
)
set /a "GetUniqueRandom.NewNumber=%random% %% %~2 +1"
rem prüfe ob die Nummer bereits gezogen wurde
echo #%GetUniqueRandom.NewNumber%#|findstr /l "dummy %GetUniqueRandom.bisherigeNummern%" >nul && (
rem wenn ja nochmal
goto :GetUniqueRandom
)
rem füge die neue Nummer der Aufzählung hinzu
set "GetUniqueRandom.bisherigeNummern=%GetUniqueRandom.bisherigeNummern% #%GetUniqueRandom.NewNumber%#"
set /a "GetUniqueRandom.allNumbers+=1" &rem zähle mit, wievele Zahlen wir schon haben
set "%~1=%GetUniqueRandom.NewNumber%"
set "GetUniqueRandom." &rem mal anzeigen , kann weg
if %GetUniqueRandom.allNumbers% geq %~2 (
echo setze Liste der bisher gezogenen Zahlen zurück! &rem Zeile kann weg
set "GetUniqueRandom.bisherigeNummern="
set "GetUniqueRandom.allNumbers=0"
)
mit den Dateien und ohne die Debugzeilen , sieht es dann so aus:
@echo off
chcp 65001 >nul
for /f "tokens=1* delims=[]" %%a in ('dir /s /b "c:/windows\Media\*.wav" ^|find /v /n ""') do (
set "myWavArray.%%a=%%b"
set "myWavArray.Count=%%a"
)
if "myWavArray.Count"=="" (
echo Keine wav!
pause
exit /b
)
call :GetUniqueRandom MyIndex %myWavArray.Count%
echo %MyIndex%
call echo %%myWavArray.%MyIndex%%%
call :GetUniqueRandom MyIndex %myWavArray.Count%
echo Zufallszahl: %MyIndex%
call echo %%myWavArray.%MyIndex%%%
call :GetUniqueRandom MyIndex %myWavArray.Count%
echo Zufallszahl: %MyIndex%
call echo %%myWavArray.%MyIndex%%%
call :GetUniqueRandom MyIndex %myWavArray.Count%
echo Zufallszahl: %MyIndex%
call echo %%myWavArray.%MyIndex%%%
call :GetUniqueRandom MyIndex %myWavArray.Count%
echo Zufallszahl: %MyIndex%
call echo %%myWavArray.%MyIndex%%%
echo:
pause
exit /b
:::: Subroutines :::
:GetUniqueRandom %1=VariablenName %2=höchste Zufallszahl
if "%~2"=="1" (
set "%~1=1"
exit /b 1
)
set /a "GetUniqueRandom.NewNumber=%random% %% %~2 +1"
echo #%GetUniqueRandom.NewNumber%#|findstr /l "dummy %GetUniqueRandom.bisherigeNummern%" >nul && (
goto :GetUniqueRandom
)
set "GetUniqueRandom.bisherigeNummern=%GetUniqueRandom.bisherigeNummern% #%GetUniqueRandom.NewNumber%#"
set /a "GetUniqueRandom.allNumbers+=1"
set "%~1=%GetUniqueRandom.NewNumber%"
if %GetUniqueRandom.allNumbers% geq %~2 (
set "GetUniqueRandom.bisherigeNummern="
set "GetUniqueRandom.allNumbers=0"
)
die Liste der bisherigen ZufallsZahlen wird erst Zurück gesetzt wenn alle möglichen gezogen wurden...
Einen Wehrmutstropfen hat die Sache. Bei sehr vielen möglichen Zahlen, kann es eine Weile dauern, bis eine Zufallszahl gefunden wird, welche noch nicht da war:
@echo off
chcp 65001 >nul
set "maxNumber=300"
for /l %%a in (1,1,%maxNumber%) do (
call :GetUniqueRandom MeineVariable %maxNumber%
call echo %%MeineVariable%%
)
pause
exit /b
:::: Subroutines :::
:GetUniqueRandom %1=VariablenName %2=höchste Zufallszahl
if "%~2"=="1" (
set "%~1=1"
exit /b 1
)
set /a "GetUniqueRandom.NewNumber=%random% %% %~2 +1"
echo #%GetUniqueRandom.NewNumber%#|findstr /l "dummy %GetUniqueRandom.bisherigeNummern%" >nul && (
goto :GetUniqueRandom
)
set "GetUniqueRandom.bisherigeNummern=%GetUniqueRandom.bisherigeNummern% #%GetUniqueRandom.NewNumber%#"
set /a "GetUniqueRandom.allNumbers+=1"
set "%~1=%GetUniqueRandom.NewNumber%"
if %GetUniqueRandom.allNumbers% geq %~2 (
set "GetUniqueRandom.bisherigeNummern="
set "GetUniqueRandom.allNumbers=0"
)
siehe Fortsetzung...
Fortsetzung:
so ist es besser:
@echo off
chcp 65001 >nul
set "maxNumber=300"
for /l %%a in (1,1,%maxNumber%) do (
call :GetUniqueRandom2 MeineVariable %maxNumber%
call echo %%MeineVariable%%
)
pause
exit /b
:::: Subroutines :::
:GetUniqueRandom2 %1=VariablenName %2=höchste Zufallszahl
if "%~2"=="1" (
set "%~1=1"
exit /b 1
)
set /a "GetUniqueRandom2.NewNumber=%random% %% %~2 +1"
echo #%GetUniqueRandom2.NewNumber%#|findstr /l "dummy %GetUniqueRandom2.bisherigeNummern%" >nul && (
goto :GetUniqueRandom2
)
set "GetUniqueRandom2.bisherigeNummern=%GetUniqueRandom2.bisherigeNummern% #%GetUniqueRandom2.NewNumber%#"
set /a "GetUniqueRandom2.allNumbers+=1"
set "%~1=%GetUniqueRandom2.NewNumber%"
set "GetUniqueRandom2.Limit=%~2"
rem sollte ok sein, wenn sich Zahlen nach 20x wiederholen können
if %GetUniqueRandom2.Limit% gtr 20 (
set "GetUniqueRandom2.Limit=20"
)
if %GetUniqueRandom2.allNumbers% geq %GetUniqueRandom2.Limit% (
set "GetUniqueRandom2.bisherigeNummern="
set "GetUniqueRandom2.allNumbers=0"
)
Danke. - Ich bin an der Entwicklung eines Menüsystems für Telefonanrufe. Dem Anrufer sollen u.a. zufällig ausgewählte Audiodateien (wav) vorgespielt werden (den Code dazu hast Du mir netterweise schon vorgeschlagen). Zufällig sollte es darum sein, um die Wahrscheinlichkeit der mehrfachen Wiedergabe desselben Audios zu minimieren. Ganz ausschliessen, zumindest für den aktuellen Anruf, lässt sich die mehrfache Wiedergabe ja nun, wenn man die bereits abgespielten Audios von der Gesamt-Dateimenge abzieht. Ich dachte erst, die Realisierung dieser Methode als cmd-Batch sei für mich zu schwierig bzw. die Einbettung in das Menüsystem. Mein Irrtum in meinem OP von diesem Thread war auch, dass es die neuste wav-Datei sein müsste in der Dateimenge abzüglich der schon gespielten Audios. Aber so würde dem selben Anrufer bei seinem nächsten Anruf immer dieselbe Reihenfolge abgespielt. Denn, Filtrierung mittels Anrufernummer ist leider nicht möglich, da mein Telcom-Anbieter nur die Mehrwertnummer übermittelt, wenn jemand darauf anruft. Wenn Letzteres nicht der Fall ist, wird die effektive Anrufernummer übermittelt. So müsste der Anrufer eine individulle Pin hinterlegen, damit bei seinem nächsten Anruf seine persönlichen bereits-abgespielt-Audios von der Gesamt-Dateimenge abgezogen werden könnte. - Nun, ich denke ich werde die Menge der bereits gespielten Audios auf diese Weise von der Gesamtmenge abziehen: Jede abgespielte Datei wird in ein temporäres Verzeichnis verschoben, so dass die Gesamtmenge, aus der per Zufall ein Audio gezogen wird, um diese bereits gespielte Datei kleiner wird. Bei Anrufende werden die Dateien im temporären Verzeichnis wieder zurückverschoben. Sehr einfach. Aber für meine Anforderung voll ausreichend.