skyemugen
Goto Top

Mehrere Dateien im Batch per Drag und Drop bearbeiten lassen

Aloha zusammen!

Ich weiß, es ist Sonntag Nachmittag und darum kriege ich wahrscheinlich einfach keine Lösung zusammen aber ich hoffe dennoch, dass ihr mir erneut bei einer kleinen Sache helfen könnt.

Also es geht um folgendes:

Auf einem ROOT von einem Privat-MMORPG liegen tausende von .ini Dateien (Spielerdateien), die für gewisse Dinge bearbeitet werden müssen aber nicht immer alle, sondern nur ausgewählte. (werden zur Not auf den lokalen PC zwischenkopiert, bearbeitet und wieder zurückkopiert.

Ich habe das Skript für eine einzelne Datei für D&D bereits realisiert (in diesem Fall für das Addieren von Skillpunkten), doch scheitere ich daran, dies für mehrere Dateien gleichzeitig umzusetzen, sprich z.B. 100 Dateien auf das Batch ziehen und durchackern lassen.

Der code sieht momentan wie folgt aus:

@echo off & setlocal

set "Datei=%1"  

set "fest=Skillpoints="  

set /p Bonus="Bitte gebe die Hoehe der Bonus-Skillpunkte an: "  

for /f "tokens=2 delims=^=" %%i in ('findstr /n "^" %1^|findstr "^13:"') do set SP=%%i  

echo Skillpunkte vorher: %SP%

set /a Skillpunkte=%SP%+%Bonus%

echo Skillpunkte nachher: %Skillpunkte%

set "Von=%fest%%SP%"  
set "Nach=%fest%%Skillpunkte%"  

set R=%temp%\ReplaceInFile.vbs
>%R% echo Set fso=CreateObject("Scripting.FileSystemObject"):Set a=WScript.Arguments:T=fso.OpenTextFile(a(0)).ReadAll:fso.CreateTextFile(a(0)).Write Replace(T,a(1),a(2))  

cscript //nologo %R% "%Datei%" "%Von%" "%Nach%"  

pause

Soweit, so gut. Ich habe versucht per
 for %%f in (%*) do (
DasganzeSkripthinterher
)
es für mehrere Dateien ausgeführt zu bekommen, das haut aber nicht ganz hin. Ich nehme an, die einzelne Datei muss anders definiert werden(?) ...

Habe bereits ein wenig im Forum danach geforstet, allerdings ohne Erfolg für meine Umsetzung.

Also bin ich dieses Mal auf eure Hilfe, Ratschläge etc. angewiesen. =)

greetz André

EDIT Das VBS überschreibt ja jetzt sämtliche Vorkommnisse von %Von% mit %Nach%, allerdings habe ich im Skript für die Leveländerung mehrfach einen Level drin (daher auch die Zeilenbeschränkung im Skript), der aber nur in der gewählten Zeile überschrieben werden darf.
Wie kann ich dieses per VBS realisieren, bin auf nichts brauchbares gestoßen, was ich hier einbauen könnte ... hm

Content-ID: 160673

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

Ausgedruckt am: 23.11.2024 um 13:11 Uhr

Friemler
Friemler 13.02.2011 um 17:11:50 Uhr
Goto Top
Hallo André,

hast Du bei Deinen Versuchen mit
 for %%f in (%*) do (
DasganzeSkripthinterher
)
an die verzögerte Erweiterung von Variablen gedacht? Timo's alter Tipp, beim Fehler suchen das @echo off wegzulassen könnte da helfen...

Gruß
Friemler
Skyemugen
Skyemugen 13.02.2011 um 17:21:12 Uhr
Goto Top
Aloha,

verzögerte Erweiterung? ....

Bei mir geht das Fenster direkt zu, da ist nix mit Fehlersuche per echo on (soweit war ich auch schon ^.^)

greetz André
Friemler
Friemler 13.02.2011 um 17:31:55 Uhr
Goto Top
Hallo André,

  1. Böse Fenster, die sich nach Skriptende einfach schließen, kann man durch einen Pause-Befehl als letztem Kommando im Skript daran hindern.
  2. Zum Thema "Verzögerte Variablenerweiterung" einfach mal Google oder die Suchfunktion des Forums befragen. Das Thema ist schon zu oft durchgekaut worden und gehört zum Grundlagenwissen für Batch-Programmierung. Nix für ungut, aber wenn Du Batch-Skript lernen willst, musst Du Dich mit dem Thema sowieso beschäftigen.

Gruß
Friemler
Skyemugen
Skyemugen 13.02.2011 um 17:42:19 Uhr
Goto Top
Aloha,

ich habe 3x pause im Skript (während und nach der for-Schleife), da ich eh die einzelnen Schritte testen musste, habe sie nur hier im Forum rausgenommen.

*puhh* „Verzögerte Variablenerweiterung“ nungut, dann wollen wir uns mal da schlau machen, wenn es diesbezüglich hilfreich ist ;)

greetz André
60730
60730 13.02.2011 um 18:46:42 Uhr
Goto Top
moin,

ohne eine Steuerdatei macht das testen des Schnippsels keinen allzugroßen Sinn (für uns)face-wink
Ich kann nur sehen, dass du irgendwas mit der Zeile 13 machst,
Und du willst alle Zahlen behalten, außer die in der Zeile 13?

Gruß
Skyemugen
Skyemugen 13.02.2011 um 19:05:33 Uhr
Goto Top
Aloha T-Mo,

ja das war ja anfangs nicht so gedacht (läuft in diesem Fall mit Skillpunkten auch ohne Zeile aber woanders eben nicht)

aber ich kann dir gerne mal einen Auszug aus einer der .ini Dateien bieten =)

[account]
password=1234567
[Data]
Guild=0
name=Test
level=57
Chartype=1916
XSection=134
YSection=97
XPos=-112
YPos=985
ZPos=-4
Skillpoints=640474
AttributePoints=168
Expirience=4398854
Race=0
GameMaster=False
Hp=2303
Mp=2303
ActualHp=2303
ActualMp=2303
MaxPhyAttack=525
MaxMagAttack=498

etc. etc.

[item0]
type=CH
amount=1
ID=338
plusvalue=0
durability=84
phyreinforce=10
magreinforce=10
phyattack=0
magattack=0
level=45
Gender=1
Race=0
PhyDef=29

u.v.m.

Das VBS-Problem mit der Zeile überschreiben (siehe Edit im EP) besteht nur bei level= in Zeile 6, da level= mehrfach später vorkommt für Items, Skills etc. (hatte das Skript für level erst später angefangen, darum fiel mir das Problem in dem hier geposteten Code für Skillpunkte nicht auf)

Wie gesagt: Ich lese den Wert in der definierten Zeile aus, füge eine Änderung hinzu und möchte ihn in der Datei überschreiben, jedoch nur in der definierten Zeile. (was für Skillpunkte nicht relevant ist, da dies nur einmal vorkommt)
Sprich: vorher steht z.B. level=57 (oder in diesem Fall Skillpoints=640474) ich setze per set /p eine Erhöhung fest, welche dann in die Datei überschrieben werden soll z.B. %Eingabe%=5 -> level=62 (oder %Eingabe%=500000 -> Skillpoints=1140474).

@Friemler

Ja, mit enabledelayedexpansion bekomme ich nun die for-Schleife anfangs zum Laufen (muss ich alle definierten %Variablen% in !Variable! setzen?), allerdings dennoch nur für eine Datei. Gib' mir doch mal bitte noch einen weiteren Wink, was ich beachten muss (so wirklich schlau aus dem for-tutorial werde ich nicht unbedingt).

greetz André
bastla
bastla 13.02.2011 um 19:09:39 Uhr
Goto Top
Hallo Skyemugen!

Je nachdem, ob für jede Datei einzeln die Bonuspunkte eingegeben werden sollen oder nicht, wäre die "set /p"-Zeile in der Schleife oder bereits vor dem ":Loop" zu platzieren:
@echo off & setlocal
set "fest=Skillpoints="  

set R=%temp%\ReplaceInFile.vbs
>%R% echo Set fso=CreateObject("Scripting.FileSystemObject"):Set a=WScript.Arguments:T=fso.OpenTextFile(a(0)).ReadAll:fso.CreateTextFile(a(0)).Write Replace(T,a(1),a(2))  

:Loop
if "%~1"=="" goto :eof  
echo %~1
set /p Bonus="Bitte gebe die Hoehe der Bonus-Skillpunkte an: "  
for /f "tokens=2 delims=^=" %%i in ('findstr /n "^" %1^|findstr "^13:"') do set "SP=%%i"  
echo Skillpunkte vorher: %SP%
set /a Skillpunkte=SP+Bonus
echo Skillpunkte nachher: %Skillpunkte%
set "Von=%fest%%SP%"  
set "Nach=%fest%%Skillpunkte%"  
cscript //nologo %R% %1 "%Von%" "%Nach%"  

pause
shift
goto :Loop
Grüße
bastla
rubberman
rubberman 13.02.2011 um 19:15:02 Uhr
Goto Top
Hallo zusammen.

SETLOCAL ENABLEDELAYEDEXPANSION ist sicher ein Weg den man gehen könnte. Ebensogut könnte man auch das Script als Subroutine aufrufen.

for %%f in (%*) do ( 
  set "arg=%%f"  
  call :sub
)
goto :eof

:sub
:: mach was mit Variable %arg%
goto :eof

Grüße
rubberman
Skyemugen
Skyemugen 13.02.2011 um 19:19:22 Uhr
Goto Top
Aloha bastla!

Ah, per Loop ich habe noch sehr viel zu lernen, nichtmal an so etwas gedacht, ja das funktioniert wunderbar!
Ich danke dir vielmals! =)

Tja, das Threadproblem wäre gelöst, ob du mir auch erneut bei meinem EDIT im Eingangsposting unter die Arme greifen könntest? =)

Wie ich T-Mo bereits schrieb, habe ich für die Änderung des Levels das Problem, dass level= mehrfach in der .ini vorkommt aber nur für die definierte Zeile (in diesem Fall Zeile 6) überschrieben werden darf.

greetz André

P.S.: Ich grübel immernoch, wo der große Unterschied zwischen %1 und %~1 ist also bei der Behandlung im Batch.
bastla
bastla 13.02.2011 um 19:22:38 Uhr
Goto Top
Hallo Skyemugen!
Ich grübel immernoch, wo der große Unterschied zwischen %1 und %~1 ist also bei der Behandlung im Batch.
%1 kann unter Anführungszeichen stehen, %~1 hat sicher keine drumherum ...
Nochmals, zur Sicherheit: Ist die Nummer der Zeile, in der überschrieben werden darf, immer gleich, bzw (einfacher) soll immer in der ersten passenden Zeile geändert werden? In letzterem Fall wäre das VBScript nur ein wenig zu ergänzen:
>%R% echo Set fso=CreateObject("Scripting.FileSystemObject"):Set a=WScript.Arguments:T=fso.OpenTextFile(a(0)).ReadAll:fso.CreateTextFile(a(0)).Write Replace(T,a(1),a(2),1,1)
Grüße
bastla
Skyemugen
Skyemugen 13.02.2011 um 19:23:21 Uhr
Goto Top
Aloha rubberman,

in der Tat, das wäre eine sogar übersichtlichere Option als das ganze Skript in die Schleife zu kloppen.

Ich muss mir mal wirklich angewöhnen an solche Dinge zu denken ... man hat halt doch zu wenig mit dem Stoff zu tun.

Auf jeden Fall danke ich auch dir für deinen Beitrag. =)

greetz André
Skyemugen
Skyemugen 13.02.2011 um 19:26:12 Uhr
Goto Top
Aloha,

Ja, die Zeilen sind (zumindest was die Charaktereigenschaften angeht) fest und in jeder .ini gleich. Dein beziehungsweise ist korrekt, es handelt sich immer um die erstpassenste Stelle.

greetz André

P.S.: Wieder was dazugelernt.

Edit: Ah dein tolles Edit ist genau die Lösung, ich danke dir erneut - jetzt kann das Überarbeiten der files endlich sauber automatisiert ablaufen (und nicht wie vor zwei Tagen 1200 files manuell ...)

Aber ob du mir noch den Gefallen tun könntest und die „Erweiterung“ des VBS erläutern könntest, bitte? =)

greetz André
bastla
bastla 13.02.2011 um 19:30:34 Uhr
Goto Top
Hallo Skyemugen!

Trotzdem noch die Variante mit der festen Zeilennummer (genauso ungetestet wie der Rest, den ich da oben verbrochen habe face-wink):
@echo off & setlocal
set "fest=Skillpoints="  
set /a Zeile=6

set /a Zeile-=1
set R=%temp%\ReplaceInFile.vbs
>%R% echo Set fso=CreateObject("Scripting.FileSystemObject"):Set a=WScript.Arguments:T=Split(fso.OpenTextFile(a(0)).ReadAll,vbCrLf):T(%Zeile%)=Replace(T(%Zeile%),a(1),a(2)):fso.CreateTextFile(a(0)).Write Join(T,vbCrLf)  

:Loop
...
Hier wird bei Einlesen durch "Split()" anhand der Zeilenschaltung ("vbCrLf" - ich setze einmal Windows-Standard voraus) ein 0-basiertes Array erzeugt, sodass sich die Zeile 6 dann in T(5) befindet - nur darin wird auch ersetzt. Abschließend wird das Array wieder (mit Trennzeichen "vbCrLf") ge"join"ed in die Datei geschrieben.

[Edit2 + 3] Fehlendes "T(%Zeile%)=" ergänzt [/Edit2 + 3]
[Edit] Die andere Version oben hat nur als Erweiterung des "Replace()" die Angaben für "Anfangsposition" (=1. Zeichen des Dateiinhalts) und "Anzahl der Ersetzungen" (= 1, also nur das allererste Vorkommen) erhalten ... [/Edit]

Grüße
bastla
Skyemugen
Skyemugen 13.02.2011 um 19:40:33 Uhr
Goto Top
Aloha bastla!

Schaut interessant aus, bringt aber eine Fehlermeldung als Nebenwirkung:

Beim Aufrufen einer Unterroutine (Sub) dürfen keine Klammern verwendet werden

(1, 147)

Nunja, deine erste Erweiterung des VBS-Parts tut ihren Dienst =)

Zu deinem Edit: Ja so etwas ahnte ich aber besser klug gefragt als dumm gestorben ;)

Grüße, André

EDIT: Zitat von meinem vorgesetzten Head-Administrator: „Ich könnte ihn küssen, den Goldjungen!“ *g*
bastla
bastla 13.02.2011 um 19:45:06 Uhr
Goto Top
Hallo Skayemugen!
besser klug gefragt als dumm gestorben ;)
FULL ACK
Die Varaiante 2 sollte jetzt (wo das fehlende "T=" nachgetragen ist), eigentlich auch eine bessere Chance haben ... face-wink

[Edit]Noch besser wird's nur, wenn auch noch "(%Zeile%)" hinzugefügt wird ... face-wink [/Edit]

Zitat von meinem vorgesetzten Head-Administrator: „Ich könnte ihn küssen, den Goldjungen!“ *g*
Das ist ja schön face-smile - ob Du mich wohl bei der Aktion vertreten könntest? face-wink

Grüße
bastla
Skyemugen
Skyemugen 13.02.2011 um 19:56:59 Uhr
Goto Top
Aloha bastla! =)

T= ... tja nun Tee ist gleich
Array ist unveränderlich oder momentan gesperrt.: 'T'

(1, 123)

Aber apropros, einen Tee werde ich mir jetzt auch machen - möchte noch jemand? ;)

Grüße, André

P.S.: Wenn du wüsstest, was mein HAdm. für ein bezauberndes Mädel ist :P

Edit Hehe, ja deine letzte Änderung hat es zum Laufen gebracht ^.^ jetzt wagt sich die Shell nicht mehr blöde Fehlermeldungen auszuspucken.
bastla
bastla 13.02.2011 um 19:58:58 Uhr
Goto Top
Hallo Skyemugen!

Die Fehlermeldung ist ja dann mal eine Abwechslung face-wink - inzwischen habe ich aber sogar getestet - Ergebnis / Schlussfolgerung: siehe oben ...
P.S.: Wenn du wüsstest, was mein HAdm. für ein bezauberndes Mädel ist :P
Da siehst Du mal, wie gut ich zu Dir (aber auch ihr face-big-smile) bin ...

Grüße
bastla

P.S.: Gedauert hat das Ganze eigentlich nur darum etwas länger, weil ich mit Tee nix am Hut hab ... face-wink
bastla
bastla 13.02.2011 um 20:16:05 Uhr
Goto Top
... und um das jetzt noch zu einem wirklich vernünftigen Ende zu bringen, parametrisieren wir die Zeilennummer auch noch:
@echo off & setlocal 
set "fest=Skillpoints="   
set /a Zeile=6 

set R=%temp%\ReplaceInFile.vbs 
>%R% echo Set fso=CreateObject("Scripting.FileSystemObject"):Set a=WScript.Arguments:Z=a(3)-1:T=Split(fso.OpenTextFile(a(0)).ReadAll,vbCrLf):T(Z)=Replace(T(Z),a(1),a(2)):fso.CreateTextFile(a(0)).Write Join(T,vbCrLf)   
...
cscript //nologo %R% %1 "%Von%" "%Nach%" %Zeile%  
...
Jetzt zieht das Script gleich selbst die 1 ab (um auf den richtigen Index zu kommen) und es könnte bei Bedarf auch in mehreren Zeilen ersetzt werden - einfach mehrmals das Script mit der entsprechenden Zeilennummer aufrufen ...

Grüße
bastla
Skyemugen
Skyemugen 13.02.2011 um 20:30:30 Uhr
Goto Top
Index außerhalb des gültigen Bereichs.

(1, 76)

Faszinierend ;)

Grüße, André
bastla
bastla 13.02.2011 um 20:33:37 Uhr
Goto Top
Hallo Skyemugen!

Du hast beim Aufruf mit "cscript" aber schon auch die Zeilennummer mit übergeben (siehe Zeile 8 im Listing oben)?

Grüße
bastla
Skyemugen
Skyemugen 13.02.2011 um 20:39:31 Uhr
Goto Top
Zitat von @bastla:
Hallo Skyemugen!

Du hast beim Aufruf mit "cscript" aber schon auch die Zeilennummer mit übergeben (siehe Zeile 8 im Listing
oben)?

Grüße
bastla

Aloha bastla!

Nunja, also, ähm, die Zeile ja? Öhm nicht direkt, ne ^.^ Ist mir doch glatt durchgegangen *g*

Nun, dann will ich nichts angemerkt haben. ;) böse Zeile, böse, böse

Tja, dann erneuten Dank (wird im Fall mit level sogar mehrfach verwendet, da Attributpunkte abhängig sind) und einen wundervollen Sonntagabend dir noch. =)

Grüße, André