Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Textfelder innerhalb einer Batch mit User-Angaben aktualisieren

Frage Entwicklung Batch & Shell

Mitglied: TexMex

TexMex (Level 1) - Jetzt verbinden

13.07.2011 um 17:15 Uhr, 2993 Aufrufe, 6 Kommentare

Hallo!

Ich habe eine Batch-Datei erstellt, die dem User die Möglichkeit gibt, einen bestimmte Nummer aus einer Liste zu wählen. Doch diese Nummern müssten auch aktualisiert werden und genau da liegt das Problem...

Das Problem bei der ganzen Geschichte ist, dass diese Update-Funktion auf Variablen aufbaut und die Lösungsansätze, die ich in diesem Forum und auch via Google gefunden habe, funktionieren leider nicht bei mir...

Ich habe mir einen kleinen Druckassistenten gebastelt (in diesem Fall alpha.bat) und möchte via update.bat diese bearbeiten. Dabei soll der User selber aussuchen, welcher Auftrag aktualisiert werden soll und wie der neue Name dann lauten soll.

01.
set "Datei=alpha.bat" 
02.
set /p from="Welcher Auftrag soll ersetzt werden? Bitte eingeben:" 
03.
set /p to="Welcher Auftrag soll dafuer eingesetzt werden? Bitte eingeben:" 
04.
set "t=%temp%\text.tmp" 
05.
if exist "%t%" del "%t%" 
06.
for /f "usebackq delims=" %%i in ("%Datei%") do set "Line=%%i" & set Line=!Line:%from%=%to%! & echo !Line!>>"%t%" 
07.
move /y "%t%" "%Datei%" 
08.
echo Schritt 1/3 erledigt! 
09.
pause > nul 
10.
 
11.
if %from% GEQ 81234567 set from01="Glas Wasser"&goto step2 
12.
echo Es ist ein Fehler aufgetreten! 
13.
goto ende 
14.
 
15.
:step2 
16.
echo Jetzt muss der Name eingegeben werden: 
17.
set "Datei=alpha.bat" 
18.
echo Alter Auftragsname: %from01% 
19.
set /p to01="Neuer Auftragsname:" 
20.
set "t=%temp%\text.tmp" 
21.
if exist "%t%" del "%t%" 
22.
for /f "usebackq delims=" %%i in ("%Datei%") do set "Line=%%i" & set Line=!Line:%from01%=%to%! & echo !Line!>>"%t%" 
23.
move /y "%t%" "%Datei%"
Dieser Code basiert auf einem Vorschlag von bastla, aber so will es nicht funktionieren, denn ich habe zuerst Fehlermeldungen bekommen, dass der bei %to% eingesetzte Wert nicht syntaktisch ausgelesen werden kann. Außerdem wird dann der gesamte Inhalt der alpha.bat gelöscht und stattdessen steht dort nur noch:

01.
!Line! 
02.
!Line! 
03.
!Line! 
04.
usw....
Bei den eingesetzten Werten (also bei from/to) handelt es sich jeweils um rein numerische Werte (in diesem Fall 81234567), ich würde das Ganze aber dann auch nochmal gerne mit kurzen Begriffen (Bsp: Glas Wasser) nutzen können. Leider lässt sich das schlecht kombinieren, ich muss leider für jeden vorhandenen Auftrag eine if-Abfrage erstellen und dann via GEQ mit den vorhandenen Nummern vergleichen... Ist bei 20 Varianten etwas blöd, aber das sollte ja eigentlich funktionieren.

Es müsste doch eine allgemeine Lösung geben, bei der statt einem Haufen Datenmüll nur die entsprechende Stelle ausgewechselt wird, oder? Den Quelltext habe ich schließlich richtig kopiert und eingesetzt...
Mitglied: Friemler
13.07.2011 um 18:03 Uhr
Hallo TexMex,

dass Dein Script nur Datenmüll ausspuckt liegt daran, dass Du den Befehl SetLocal EnableDelayedExpansion nicht in die erste Scriptzeile geschrieben hast. Wenn Du jetzt nicht weißt, was das ist, befrage Google zum Thema "verzögerte variablenerweiterung".

Ich würde das aber anders lösen. Statt die alpha.bat für jeden Begriff neu zu schreiben, würde ich den Begriff beim Aufruf als Parameter übergeben, z.B. so:
call alpha.bat "Glas Wasser"
Innerhalb von alpha.bat kannst du dann über die Parametervariable %1 auf den übergebenen Begriff zugreifen.

Da der Begriff hier ein Leerzeichen enthält, muss er in der Aufrufzeile in Anführungszeichen eingeschlossen werden. Um die innerhalb von alpha.bat wieder loszuwerden, musst Du den Ausdruck %~1 verwenden. Die Tilde entfernt die Anführungszeichen.

Da damit Deine Fragen aber sicherlich noch nicht beantwortet sind, ich aber auch Dein genaues Problem mit "Zahlen auswählen bzw. aktualisieren" nicht verstanden habe (dürfte bei der Beschreibung aber anderen auch so gehen ), wäre es am besten wenn Du zumindest nochmal Den Inhalt der alpha.bat postest und besser erklärst, was Du eigentlich erreichen willst.

Gruß
Friemler
Bitte warten ..
Mitglied: TexMex
13.07.2011 um 22:54 Uhr
Alles klar, Friemler.

Ich erkläre gerne den genauen Aufbau meiner Batch-Datei, werde aber auch nochmal morgen deinen Tipp mit "EnableDelayedExpansion" aufgreifen. Hatte daran nämlich gar nicht gedacht, weil ich diese Zeile bei einer weiteren Update-Anwendung (die aber andere Fehler aufweist und von daher ohnehin nicht relevant ist) eingebaut hatte.

Also, allgemein gibt es zwei Batch-Dateien, mit denen ich arbeite (bzw. arbeiten möchte):

In diesem Fall nennen wir sie:
auftrag.bat (statt wie oben alpha.bat)
update.bat (aus der der oben gezeigte Ausschnitt stammt)

auftrag.bat:
---
Mit der Datei "auftrag.bat" habe ich eine allgemeine Menü-Oberfläche, bei der der Benutzer aus verschiedenen Aufträgen den gewünschten raussucht. Das läuft über eine simple choice-Abfrage ab und erstellt dabei noch eine entsprechende Variable.
Ich nehme hier einfach wieder als Beispiel die Auftragsnummer 81234567, hinter welcher der Auftrag "Glas Wasser" steckt. Es gibt dann noch weitere Auftrage (81235678 Glas Cola; 81236789 Glas Limo)

In der Batch sieht das wie folgt aus:
01.
set prod=8123 
02.
echo Auftrag waehlen 
03.
echo ---- 
04.
echo. 
05.
echo [1] 81234567 Glas Wasser 
06.
echo. 
07.
echo [2] 81235678 Glas Cola 
08.
echo. 
09.
echo [3] 81236789 Glas Limo 
10.
 
11.
choice /c:123 /n 
12.
 
13.
if errorlevel 1 set print=4567 & goto pref 
14.
if errorlevel 2 set print=5678 & goto pref 
15.
if errorlevel 3 set print=6789 & goto pref
Die Variablen %prod% und %print% sind dazu da, dass ich auch andere Aufträge (z.B. 80001234) aus diesem Schema zusammensetzen kann. Für die oben erwähnte Auftragsgruppe (8123xxxx) erscheint diese Zweiteilung sinnlos, aber im Gesamtbild ergibt sie durchaus Sinn. Dieser Teil des Scripts funktioniert auch tadellos, tut hier also eigentlich nichts zur Sache, ich erwähne sie an dieser Stelle nur zur Erklärung.

So...

Jetzt möchte ich mit Hilfe der "update.bat" die Informationen in der "druck.bat" verändern bzw. aktualisieren.

Zum Beispiel soll dann aus der "81234567" und dem dazugehörigen "Glas Wasser" zum Beispiel "80001234" mit dem Namen "Tasse Tee" werden. Diese Änderung soll dann dauerhaft so hinterlegt werden, deswegen möchte ich eigenltich nicht auf den "call"-Befehl zurückgreifen, da er mir doch nur einen temporären Nutzen bringen würde.

Ich hatte es auch schon im Prinzip soweit eingetellt, dass man lediglich die entsprechende Nummer (also 81234567) eintippen konnte (ich habe für unsichere User auch die Möglichkeit eingebaut, dass sie aus einem Menü den entsprechenden Eintrag raussuchen konnten - wieder mit if-Anfrage, aber am Ende steht das selbe Ergebnis), das Script den Namen (also in diesem Fall "Glas Wasser") via if-Abfrage raussucht, anzeigt und dann wiederum die Möglichkeit zur Änderung bietet.

Aber wie bereits erwähnt wird bei mir trotz der Abfrage, welcher Auftrag geändert werden soll und auch die Eingabe und Erkennung funktioniert, einfach der gesamte Inhalt aus "druck.bat" gelöscht und dafür wird dann "!Line!" eingesetzt...

Ich hoffe, ich konnte jetzt erklären, wo das Problem liegt und was ich mit dieser Batch-Datei eigentlich erreichen möchte. Mir ist durchaus bewusst, dass diese ganzen Bezeichnungen und Nummern für Außenstehende kryptisch wirken. Aber ich kann garantieren, dass ich das Ganze noch erheblich erleichtert habe, da die tatsächlichen Artikelnummern und -bezeichnungen um einiges undurchsichtiger sind.
Bitte warten ..
Mitglied: Friemler
14.07.2011 um 00:17 Uhr
Hallo TexMex,

also dass der Ausschnitt aus der Auftrag.bat/Druck.bat (was denn nun? ) fehlerfrei funktioniert, kann ich noch nicht glauben. Die Abfrage if errorlevel 1 ist für alle Werte von ERRORLEVEL größer oder gleich 1 wahr. Die Abfragen für die Werte 2 und 3 werden nie ausgeführt.

Entweder Du schreibst if %errorlevel% equ 1 usw. oder Du drehst die Reihenfolge der drei Abfragen um und fängst mit if errorlevel 3 an, dann geht's auch.

So, und jetzt zu Deinem Vorhaben, mit einem Batchscript Wörter in einem anderen Batchscript auszutauschen und die Datei neu zu schreiben: Vergiss es

Beweis:
  1. Speichere den Code aus Deinem Eröffnungsposting als InFile.bat
  2. Speichere das folgende Script im selben Verzeichnis und starte es.
01.
@echo off 
02.
 
03.
setlocal enabledelayedexpansion 
04.
 
05.
set "from=Datei" 
06.
set "to=File" 
07.
set "t=OutFile.bat" 
08.
 
09.
for /f "usebackq delims=" %%i in ("InFile.bat") do ( 
10.
  set "Line=%%i" 
11.
  set "Line=!Line:%from%=%to%!" 
12.
  >>"%t%" echo !Line! 
13.
)
Es wird dadurch als Ausgabe eine Datei OutFile.bat erzeugt. Schau Dir in dieser Datei mal Zeile 6 und Zeile 20 genau an... - Datenmüll!

Das Problem mit Batchscript und dem verarbeiten von Dateien mit beliebigem Inhalt ist, dass Batchscript so einige Zeichen als Steuerzeichen interpretiert, wenn sie mit ECHO ausgegeben oder von Stringersetzungsausdrücken (Zeile 11 meines Scripts) verarbeitet werden.

Alternativen:
  1. VBScript lernen und eine Update.vbs schreiben.
  2. Eine Datei verwenden, die die Einträge für das Auswahlmenü enthält und nur diese mit der Update.bat bearbeiten. Die Auftrag.bat/Druck.bat ließt die anzuzeigenden Menüeinträge aus dieser Datei. Die Menüeinträge sollten am besten nur aus Buchstaben und Zahlen bestehen.

Das könnte so gehen:

  • Die Datei mit den Menüeinträgen (als Menu.txt speichern):
01.
81234567:Glas Wasser 
02.
81235678:Glas Cola 
03.
81236789:Glas Limo
  • Die Auftrag.bat/Druck.bat:
01.
@echo off & setlocal 
02.
 
03.
 
04.
set "MenuFile=Menu.txt" 
05.
 
06.
 
07.
::Menü anzeigen 
08.
:InputLoop 
09.
cls 
10.
echo Auftrag wählen 
11.
echo ---- 
12.
echo. 
13.
 
14.
set /a Cntr=0 
15.
 
16.
::Die Menüdatei einlesen und die enthaltenen Einträge darstellen 
17.
for /f "tokens=1,2* delims=:" %%a in ('findstr /n "^" "%MenuFile%"') do ( 
18.
  echo [%%a]  %%b %%c 
19.
  echo. 
20.
  set /a Cntr+=1 
21.
22.
 
23.
echo [E]  Ende 
24.
echo. 
25.
 
26.
set "Item=" 
27.
 
28.
::Benutzereingabe einlesen 
29.
set /p "Item=" 
30.
 
31.
::E für Ende gedrückt? -> Beenden 
32.
if /i "%Item%" equ "E" exit /b 
33.
 
34.
::Wenn die Eingabe etwas anderes als Zahlen enthält, wiederholen 
35.
for /f "delims=0123456789" %%n in ("%Item%") do goto :InputLoop 
36.
 
37.
::Führende Nullen entfernen, sonst wird die Zahl als Oktalzahl aufgefasst 
38.
for /f "tokens=* delims=0" %%n in ("%Item%") do set "Item=%%n" 
39.
 
40.
::In Zahl konvertieren 
41.
set /a Item=Item 
42.
 
43.
::Bei 0, nur ENTER gedrückt oder zu großen Zahlen, wiederholen 
44.
if %Item% lss 1 goto :InputLoop 
45.
if %Item% gtr %Cntr% goto :InputLoop 
46.
 
47.
::Aus der Eingabe die Produktnummer aus der Menüdatei ermitteln 
48.
for /f "tokens=1,2 delims=:" %%a in ('findstr /n "^" "%MenuFile%"') do ( 
49.
  if %%a equ %Item% set "Prod=%%b" 
50.
51.
 
52.
::Ab hier kann mit der Produktnummer gearbeitet werden 
53.
echo %Prod% 
54.
:: 
55.
::Mach' was 
56.
:: 
57.
::Ende 
58.
exit /b
Damit kann die Menu.txt beliebig viele Einträge enthalten und die Variable Prod enthält gleich die vollständige Produktnummer. Allerdings muss jetzt bei der Eingabe ENTER gedrückt werden.

Wenn Du Dich fragst:
  • Warum setzt dieser Typ die Zuweisungen mit SET in Anführungszeichen? - So kann es nie passieren, das sich aus versehen ein Leerzeichen an den zuzuweisenden Wert anhängt; hat manche schon zur Verzweiflung gebracht.
  • Warum macht er das bei set /a Cntr=0 nicht? - Das ist wegen /a eine arithmetische Zuweisung (mit einem numerischen Wert). In diesem Fall würden versehentlich angehängte Leerzeichen ignoriert.

Übrigens: Du weißt schon, dass CHOICE unter XP nicht verfügbar ist?


Gruß
Friemler
Bitte warten ..
Mitglied: TexMex
14.07.2011 um 16:58 Uhr
Hey Friemler,

Stimmt, die choice-Abfrage, die ich dort oben gepostet habe, würde so nicht funktionieren. Da habe ich nicht genau hingeschaut und eine Abfrage aus einer alten (aber inhaltsgleichen) Sicherungskopie veröffentlicht...

Danke für deine umfangreiche Hilfe, leider funktioniert der zweite Teil deiner "Druck.bat" nicht so, wie gewollt. Ich habe dafür aber den ersten Teil in mein kleines Programm integriert, das macht den Quelltext erheblich übersichtlicher und ich konnte dadurch ja die ganzen Angaben in einer externen Datei speichern, auf die dann auch eine weitere Batch-Datei zugreifen kann.

Ich habe es jetzt etwas komplizierter, aber durchaus machbar gelöst. Die menu.txt ist ja relativ simpel aufgebaut, dementsprechend habe ich einfach eine Verknüpfung in die Batch-Datei integriert, damit der User selbst die Änderungen vornehmen kann. Ist nicht ganz optimal, aber immerhin funktioniert es.

Dass Choice unter XP nicht verfügbar ist, stellt kein Problem dar, da ich das Ganze eh nur auf Windows7-Rechnern laufen lasse.
Bitte warten ..
Mitglied: Friemler
14.07.2011 um 17:24 Uhr
Hallo TexMex,

Zitat von TexMex:
leider funktioniert der zweite Teil deiner "Druck.bat" nicht so, wie gewollt.

was meinst Du damit genau? Die Prüfungen zum abfangen von ungültigen Eingaben oder das auslesen der Produktnummer aus der Menü-Datei?

Gruß
Friemler
Bitte warten ..
Mitglied: TexMex
19.07.2011 um 10:08 Uhr
Bei mir hat er eine Fehlermeldung angezeigt.

Aber ich konnte das Problem inzwischen lösen. Ich hatte lediglich deinen Programm-Code falsch integriert und wollte ihn mit einer anderen Schleife kombinieren. Das konnte natürlich nicht funktionieren.

Jetzt funktioniert alles!

Danke für die ganze Hilfe.
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
Per Batch aktuell angemeldete User auslesen (1)

Frage von Peter32 zum Thema Batch & Shell ...

Windows 7
Gruppenrichtlinie für User auf andere Rechner übertragen (1)

Frage von Robmantuto zum Thema Windows 7 ...

Outlook & Mail
gelöst Notwendige bzw Überflüssige Angaben in Geschäftlicher Email-Signatur (11)

Frage von Knorkator zum Thema Outlook & Mail ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (20)

Frage von Xaero1982 zum Thema Microsoft ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...

Festplatten, SSD, Raid
M.2 SSD wird nicht erkannt (14)

Frage von uridium69 zum Thema Festplatten, SSD, Raid ...