wiseolli
Goto Top

Batch - Zufallszeilen aus txt-Datei anzeigen. Einige Macken im Skript

Früher hatte ich ein Programm, das mir nach einer bestimmten Zeit (z.B. nach 30 min.) auf dem Desktop verschiedene Zitate/Fremdwörter/Prüfungsfragen usw. aus einer Textdatei Zeilenweise per Zufallsgenerator anzeigen konnte. Nach und nach konnte man so die Sachen auswendig lernen.
Nun wollte ich so etwas in Batch schreiben (möglichst ohne externe Programme). Dabei bin ich auf ein paar Problemchen gestoßen.

Hallo Leute,

es gibt einige Probleme in meinem Batch-Code, die ich nicht beseitigen kann.
Vielleicht könnten mir ja die Batch-Experten unter euch auf die Sprünge helfen face-wink
(bei den Schleifen blick ich nicht so richtig durch)


back-to-topKurze Beschreibung:
  • Es wird eine Text-Datei eingelesen.
  • Jede Zeile bekommt eine Nummer davor gestellt und alles (Nr.+Textzeilen) wird in eine temporäre Datei geschrieben.
  • Per Zufallsgenerator wird eine Zeile ausgewählt und für eine festgelegte Zeit angezeigt
  • Nach einiger Zeit wird wieder eine Zufallszeile aus der Temp-Datei angezeigt usw.


back-to-topDie Macken sind:
  • Die Zeilen, die einstellige Nummern haben werden nicht angezeigt (scheinbar erst ab Zeile Nr. 10)
  • Größere Zahlen kommen öfters vor (ist nicht wirklich zufällig)
  • Manchmal werden auch zwei Zeilen auf einmal angezeigt (aber das ist nicht so schlimm wie Macke mit Zufallszahlen) z.B. Zeilen 35 und darunter 45 oder 38 und 48 gleichzeitig.


back-to-topMein Code:
@echo off
:: Variablen sind nur in diesem Fenster aktiv
setlocal

REM Skript zeigt zufällige Zeilen aus einer Textdatei an

REM Die Zitate dürfen keine Umlaute ß und andere Sonderzeichen enthalten
REM Oder man speichert die Textdatei nicht als ANSI sondern OEM oder DOS oder OEM850 als Kodierung
REM Wenn Editor das nicht kann, dann DOS-Editor (in cmd Edit eingeben)
REM evtl. muß man für andere Codepages/unicode die Console auf Lucida Schrift umstellen!
REM Damit lange Zitate nicht rechts auslaufen (mit Laufleiste) sondern automatisch umgebrochen werden, muß man beim CMD-Fenster-Eigenschaften den Breiten-Puffer dem Fenster-Puffer anpassen


::Einstellungen
::===========================================================================================================================

:: Fenstergröße Zeile,Spalte Anzahl
mode 81,5

:: Fenstertitel ändern
title ______Zitate______

:: Fensterfarbe
COLOR f1

:: Codepage des cmd-Fensters einstellen
:: Multi (DE) - für Textkodierungen wie DOS, OEM 850 u.ä.
rem CHCP 850 > nul
:: Windows 1252 - Kyrillische-Zeichen werden schon in Textdatei nicht angezeigt
CHCP 1252 > nul
:: Cyrillic - Text muß man auf OEM-855 kodieren. Umlaute werden ohne Punkte angezeigt, ß als Fragezeichen, Consolenfenster auf "Lucida Console" einstellen 
rem CHCP 855 > nul
::Russian - Text muß man auf OEM-866 kodieren. Umlaute werden ohne Punkte angezeigt. ß als Fragezeichen.  Consolenfenster auf "Lucida Console" einstellen 
rem CHCP 866 > nul
::UTF-8 - Funktioniert nicht, Fenster wird geschlossen
rem CHCP 65001 > nul

:: Pfad zu der Datei anpassen, in der die Fremdwörter/Zitate drin  stehen :
set "MyFile=Zitate.txt"  
::=================================================================================================================================



:: Falls temporäre Datei existiert, dann löschen
if exist %temp%\tmp.txt del %temp%\tmp.txt

:: Temporäre Datei mit vorangestellter Zeilennummerierung schreiben
for /f "tokens=*" %%i in ('type %MyFile%^|findstr /n .') do echo %%i>>%temp%\tmp.txt  

:: Zeilen zählen:
for /f "tokens=*" %%i in ('type %MyFile%^|findstr /n .') do for /f "delims=: tokens=1" %%j in ("%%i") do set /a counter=%%j  

:loop
cls
:: Zufallszahl von 1 bis Anzahl Zeilen
:: (Der erste Random-Aufruf geht ins Leere, weil erst beim zweiten Aufruf eine wirkliche Zufallszahl rauskommt.)
echo %random%>nul

::Komischerweise werden einstellige Zeilennummern nicht angezeigt (erst ab Zeile Nr. 10), und größere Zahlen kommen öfters vor
::set /a rdm=(%random%*%counter%/32767)+1
::set /a rdm=1+%counter%*%random%/32768

rem deshalb diese Methode probiert (Vorschlag von Biber, gefunden in [content:21951#81715]  )
rem Beispiel, wenn man Zufallszahl zwischen 1 und 500 haben will, dann Set /a Variable=%random% %500 + 1 und in Batch %%500 + 1 (ohne +1 wird auch 0 gezählt)
::auch hier wieder werden einstellige Zeilennummern nicht angezeigt, obwohl es in cmd-Fenster geht
set /a rdm=%random% %%counter + 1

::evtl. funzt die Zählschleife nicht richtig. Evtl. mit manueller Zeilennnummer machen z.B. Am Ende der Textdatei, oder am Ende eine Markierung machen z.B. ---Ende--- und dort Zeile auslesen
::Manchmal werden auch zwei Zeilen auf einmal angezeigt (aber das ist nicht so schlimm wie Macke mit Zufallszahlen) z.B. Zeilen 35 und darunter 45 oder 38 und 48

::echo.
:: Zufällige Zeile (in temporär erstellten Text-Datei) finden
echo.
findstr /L %rdm%: %temp%\tmp.txt
echo.


:: Zeit in Sekunden (wie schnell werden andere Zeilen angezeigt)
rem Zum Testen erst auf Paar Sekunden gestellt für Schnelldurchlauf
@ping -n 2 localhost> nul
cls
goto loop


rem Man kann es wohl auch ohne temp-Datei lösen, wenn man die Originalzitate durchnummeriert (ich weiß aber nicht genau wie)



Grüße (und vielen Dank schon mal im Voraus für die Hilfe)
wiseolli

Content-ID: 159731

Url: https://administrator.de/contentid/159731

Ausgedruckt am: 22.11.2024 um 13:11 Uhr

60730
60730 30.01.2011, aktualisiert am 18.10.2012 um 18:45:40 Uhr
Goto Top
Salü,

Mal zum spielen in der schwarzen Kiste ganz ohne ....

for /l %a in (1,1,100) do echo %a: a%a>>C:\script\random\123.in

findstr /l 4: C:\script\random\123.ini
  • Das ist das, was du in Zeile 74 machst und das kommt sinngemäß dabei heraus:
4: a4
14: a14
24: a24
34: a34
44: a44
54: a54
64: a64
74: a74
84: a84
94: a94

Ergo:
findstr /b /c:"4:" C:\script\random\123.ini
4: a4

Gruß
wiseolli
wiseolli 30.01.2011 um 16:55:01 Uhr
Goto Top
Hallo,

mit
for /l %a in (1,1,100) do echo %a: a%a>>%temp%\123.ini
findstr /l 4: %temp%\123.ini
findstr /b /c:"4:" %temp%\123.ini
hab ich's nun nachvollziehen können.

Vielen Dank TimoBeil!

Zeile 74 habe ich nun in
 findstr /b /c:"%rdm%:" %temp%\tmp.txt 
geändert. Und nun läufts.

Gruß
wiseolli
pieh-ejdsch
pieh-ejdsch 30.01.2011 um 17:39:21 Uhr
Goto Top
moin,

in Zeile 48 und 51 gibst Du jeweils Die Zeilennummern von der OriginalDatei aus aber blendest die Leerzeilen aus
for /f "tokens=*" %%i in ('type %MyFile%^|findstr /n .') do echo %%i>>%temp%\tmp.txt
somit kommst Du aber auf einen Falschen EndWert, wenn Du paar verstreute LeerZeilen im Original hast. - Die werden ja auch mitgezählt und dein Script zeigt nichts an, wenn genau diese Zeile rausgepickt würde.
wenn Du den genauen Zeilenwert ohne die Leerzeilen haben willst, musst Du findstr 2 mal nehmen das erste ohne Option /n
type %MyFile%|findstr  . |findstr /n "^" >%temp%\tmp.txt
wenn Du Type Datei nicht zur Konvertierung der Datei nimmst, kannst Du die Datei dem 1. Findstring so mitgeben.

in Zeile 51 kannst Du die Zeilen auch gleich mithilfe der TempDatei zählen
for /f "usebackq delims=:" %%i in ("%temp%\tmp.txt") do set /a counter=%%i
wenn Du in Zeile 74 /c: weglässt geht es auch. Du hast ja schon /b dastehen.

Gruß Phil
wiseolli
wiseolli 05.02.2011 um 15:11:55 Uhr
Goto Top
Hallo, und danke für den Kommentar Phil.

in Zeile 48 und 51 gibst Du jeweils Die Zeilennummern von der OriginalDatei aus aber blendest die Leerzeilen aus
Tatsächlich. Hab paar leere Zeilen ins Orig. eingefügt. Und wenn ich die erstellte Temp öffne, sind die Leerzeilen (und deren Anfangsnummern nicht da).

Da ich aber in den "for-Schleifen" nicht durchblicke, werde ich versuchen die Leerzeilen zu vermeiden. Und zur Not bemühe ich halt die Funktion "Delete Blank Lines" im Notepad++ face-smile

wenn Du in Zeile 74 /c: weglässt geht es auch. Du hast ja schon /b dastehen.
Stimmt, hab's probiert, geht auch ohne.
Hatte den Befehl von TimoBeil so 1:1 übernommen, da die beiden Schalter in findstr /? für mich auch passend klangen:
 /B    Sucht am Zeilenanfang.
...
  /C:Zeichenfolge   Sucht nach Zeichenfolge buchstabengetreu.

Danke für die Hinweise/Verbesserungen noch mal - Dat Ding rennt wie ich's wollte! face-smile

Gruß
wiseolli