haegar75
Goto Top

Per Batch Zeilen aus Datei in Variable schreiben

Hallo Leute,
erstmal Danke dafür, dass ich in eurem Forum schon sehr oft Hilfe bei meiner Gelegentlichen Batch-Programmierung gefunden habe.
Diesmal komme ich aber nicht weiter, so dass ich mich anmelden musste face-wink
Also:
Ich möchte IP-Adressen die ich ich in eine Datei geschrieben habe (untereinander) in eine Variable schreiben mit Semikolon getrennt.

Probiert habe ich:
for /f %%x in (ips.txt) do set ausgabe=%ausgabe% %%x

leider steht aber immer nur die letzte Zeile drin.. face-sad

Achja, die Zeilen(IPs) möchte ich dann gerne (mit Semikolon getrennt) in eine INI-Datei an eine bestimmte Stelle schreiben. Quasi
IP=xxx.xxx.xxx.xxx durch meinen Eintrag in IP=xxx.xxx.xxx.xxx;xxx.xxx.xxx.xxx; usw ersetzen.

Dank im voraus für eure Mühen!!

Content-Key: 95043

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

Printed on: April 26, 2024 at 10:04 o'clock

Member: bastla
bastla Aug 21, 2008 at 20:10:04 (UTC)
Goto Top
Hallo Haegar75 und willkommen im Forum!

Mit "delayedExpansion" sollte das klappen:
@echo off & setlocal enabledelayedexpansion
for /f %%x in (ips.txt) do set ausgabe=!%ausgabe%!;%%x
set ausgabe=%ausgabe:~1%
Was das Ersetzen in einer .ini-Datei anlangt, stellt sich immer die Frage, ob die Position der Zeile innerhalb der Datei relevant ist - falls nein, sollte (als Fortsetzung von oben) genügen:
> "D:\Deine neue.ini" findstr /v /b "IP=" "D:\Deine.ini"  
>>"D:\Deine neue.ini" echo IP=%ausgabe%  
Grüße
bastla
Member: Haegar75
Haegar75 Aug 21, 2008 at 20:21:25 (UTC)
Goto Top
Hi, das ging ja hurtig mit der Antwort!
Leider ist es immer noch das gleiche. Steht immer noch nur der letzte Wert drin. Liegts am XP?
Gruß Joachim
Member: bastla
bastla Aug 21, 2008 at 20:27:19 (UTC)
Goto Top
Hallo Haegar75!

Liegts am XP?
Liegt leider an unkonzentriertem bastla ... face-sad
Die "%"-Zeichen (ein Resultat von copy & paste) innerhalb von !%ausgabe%! sind höchst entbehrlich.

Grüße
bastla
Member: Haegar75
Haegar75 Aug 21, 2008 at 20:32:26 (UTC)
Goto Top
Joa, die Prozentzeichen warens! Aber die Unkonzentriertheit seien dem Bastla zur fortgeschrittenen Stunde verziehen face-wink
Member: Haegar75
Haegar75 Aug 22, 2008 at 16:09:44 (UTC)
Goto Top
Hi, ich schon wieder! face-sad
Leider reicht es nicht die geänderte Zeile anzuhängen,
weil der Eintrag in einem bestimmten Block der Datei stehen muss. Steht er nur untendrunter wird er nicht bearbeitet. Jetzt bin ich mal wieder mit meinem Latein am Ende.. Kann findstr evtl. die Zeilennummer ermitteln, aber wie krieg ich nen String zeilengenau in eine Datei?
Member: bastla
bastla Aug 22, 2008 at 16:34:59 (UTC)
Goto Top
Hallo Haegar75!

Wusste ich's doch ... face-wink

Na denn:
@echo off & setlocal enabledelayedexpansion
set ausgabe=
for /f "usebackq" %%x in ("D:\ips.txt") do set "ausgabe=!ausgabe!;%%x"  
set "ausgabe=%ausgabe:~1%"  

if exist "D:\Deine neue.ini" del "D:\Deine neue.ini"  
for /f "delims=" %%i in ('findstr /n $ "D:\DeineAlte.ini"') do call :ProcessLine "%%i"  
goto :eof

:ProcessLine
for /f "tokens=1* delims=:" %%a in (%1) do set "Zeile=%%b"  
echo %Zeile%|findstr /b /i "IP=">nul || (>> "D:\Deine neue.ini" echo\%Zeile% & goto :eof)  
>>"D:\Deine neue.ini" echo IP=%ausgabe%  
goto :eof
Das erste "findstr" dient eigentlich nur dazu, die Leerzeichen zu erhalten (daran dürfte Dir ja vermutlich auch gelegen sein face-wink), und das letzte "goto :eof" ist Luxus - zumindest, solange Du nicht noch weitere Batchzeilen unterhalb unterbringen willst.

Grüße
bastla
Member: Haegar75
Haegar75 Aug 22, 2008 at 20:15:53 (UTC)
Goto Top
Sorry Bastla, aber ich bekomms nicht gebacken. Das Teil steigt immer aus und ich find nicht raus warum.
Zu Hülf!! face-wink
Member: bastla
bastla Aug 22, 2008 at 20:26:28 (UTC)
Goto Top
Hallo Haegar75!

Damit die Beschreibung des Fehlers etwas spezifischer werden kann, ändere in Zeile 1 das "echo off" auf "echo on" und starte den Batch direkt von der Kommandozeile bzw füge zumindest vor Zeile 8 noch eine Zeile mit "pause" ein.

Es werden jetzt alle Befehle vor der Ausführung angezeigt - so siehst Du, welcher Befehl zuletzt ausgeführt wird, und auch, welche Werte für die Variablen jeweils eingesetzt werden.

Gibt es übrigens in der ini-Datei Sonderzeichen ("<>&|" und einzelne - also nicht paarweise in einer Zeile enthaltene - Anführungszeichen sind problematisch)?

Grüße
bastla
Member: Haegar75
Haegar75 Aug 23, 2008 at 08:17:55 (UTC)
Goto Top
Hallo Bastla,
machst du nebenher noch hellsehen!? face-wink

Also ich denke ich habe genau die zwei Probleme..
1. Der Block wo ich die Zeile einfügen möchte wird mit <xxx> begonnen und mit <xxx_end> geschlossen. Von den Blöcken gibt es mehrere, aber mein Keyword ist eindeutig und kommt nur in einem Block vor..
2. die zu ersetzende Zeile sieht so aus:
ip "111.111.111.111;222.222.222.222"
Dazu hab ich den Code auf:
for /f "usebackq" %%x in ("ips.txt") do set "ausgabe=!ausgabe!;%%x"
set "ausgabe=%ausgabe:~1%"
geändert..

Nachdem ich die Blockanfänge und Enden mal rausgeworfen habe, läuft der batch erstmal durch, aber die " machen ihn noch durcheinander.
Er sagt dann:Datei ip "111.111.111.111" nicht gefunden.

In der neuen ini steht dann anstatt der zu ersetzenden Zeile die vorhergehende Zeile quasi doppelt..
Member: bastla
bastla Aug 23, 2008, updated at Oct 18, 2012 at 16:36:08 (UTC)
Goto Top
Hallo Haegar75!

machst du nebenher noch hellsehen!? face-wink
Ist gelegentlich nicht zu vermeiden face-wink - außerdem hatten wir Ähnliches gerade nebenan ...

Wie auch dort schon erwähnt, ist VBS eigentlich die bessere Wahl, wenn es um Textoperationen geht. Allerdings lässt sich das auch in einen Batch packen, etwa so:
@echo off & setlocal enabledelayedexpansion
set "Liste=D:\ips.txt"  
set "Quelle=D:\Deine alte.ini"  
set "Ziel=D:\Deine neue.ini"  
set "Suche=IP"  

set IP=
for /f "usebackq" %%x in ("%Liste%") do set "IP=!IP!;%%x"  
set "IP=%IP:~1%"  
if not defined IP echo "Keine neuen IP gefunden - Abbruch!" & goto :eof  

set R=%temp%\ReplaceInIni.vbs
> %R% echo Set fso=CreateObject("Scripting.FileSystemObject")  
>>%R% echo Zeilen=Split(fso.OpenTextFile("%Quelle%").ReadAll,vbCrLF)  
>>%R% echo Suche=UCase("%Suche%")  
>>%R% echo Set Z=fso.CreateTextFile("%Ziel%",True)  
>>%R% echo For i=0 To UBound(Zeilen)
>>%R% echo     If UCase(Left(Zeilen(i),Len(Suche)))^<^>Suche Then
>>%R% echo         Z.WriteLine Zeilen(i)
>>%R% echo     Else
>>%R% echo         Z.WriteLine "IP ""%IP%"""  
>>%R% echo     End If
>>%R% echo Next
>>%R% echo Z.Close		
cscript //nologo %R%
Wenn Du gleich "in" der Ausgangsdatei ersetzen willst, einfach in Zeile 16 "%Quelle%" anstelle von "%Ziel%" verwenden.

Grüße
bastla
Member: Haegar75
Haegar75 Aug 23, 2008 at 10:16:46 (UTC)
Goto Top
Respekt! Funktioniert auf Anhieb! Danke! Wär es vermessen zu fragen, ob du mir evt. paar Kommentare dazuschreiben könntest? Die VBS-Zeilen sind böhmische Dörfer für mich face-wink Was muss auf dem PC installiert sein, damit das VBS im Batch funktioniert?
Gruß Haegar75
Member: bastla
bastla Aug 23, 2008 at 10:45:44 (UTC)
Goto Top
Hallo Haegar75!

Was muss auf dem PC installiert sein, damit das VBS im Batch funktioniert?
Eine besondere Installation ist nicht nötig - "cscript.exe" sollte auf jedem einigermaßen aktuellen Windows zur Verfügung stehen ...

Zum Script: Da es aus dem Batch heraus erstellt wird, können die Batchvariablen (%Quelle% etc) in das Script als Konstanten eingetragen werden.
Set fso=CreateObject("Scripting.FileSystemObject")  
Zeilen=Split(fso.OpenTextFile("%Quelle%").ReadAll,vbCrLF) 'Textdatei als Einzelzeilen in das Array "Zeilen" einlesen  
Suche=UCase("%Suche%") 'Suchbegriff (wird durch den Batch eingetragen) in Großbuchstaben umwandeln (damit das Finden nicht an Groß-/Kleinschreibung scheitert)  
Set Z=fso.CreateTextFile("%Ziel%",True) 'Zieldatei erzeugen  
For i=0 To UBound(Zeilen) 'Alle Zeilen einzeln durchgehen  
	If UCase(Left(Zeilen(i),Len(Suche)))^<^>Suche Then 'Wenn der Suchbegriff nicht am Anfang der Zeile (= "Links" in der Zeile ;-)) steht, bzw noch genauer: mit den ersten, sich aus der Länge des Suchbegriffes ergebenden, x Zeichen (ebenfalls auf Großbuchstaben umgewandelt), übereinstimmt ...  
		Z.WriteLine Zeilen(i) '... die Zeile unverändert in die Zieldatei schreiben ...  
	Else
		Z.WriteLine "IP ""%IP%""" '... anderenfalls durch den neuen Eintrag ersetzen (Anführungszeichen müssen verdoppelt werden, um als "normales" Zeichen interprtiert zu werden)  
	End If
Next
Z.Close 'Zieldatei schließen  
Das vom Batch "maßgeschneiderte" Script kannst Du Dir auch mit
notepad "%temp%\ReplaceInIni.vbs"  
im Editor ansehen.

Noch als Anmerkung zur Schreibweise "^<":
Da "<" (und auch die anderen oben bereits genannten Sonderzeichen) in Batch eine besondere Bedeutung haben, müssen sie "maskiert" werden - damit wird der CMD-Interpreter angewiesen, sie eben nicht zu interpretieren face-wink, sondern als "gewöhnliche" Zeichen auszugeben.

Grüße
bastla
Member: Haegar75
Haegar75 Sep 22, 2008 at 19:26:57 (UTC)
Goto Top
Nabend! Ich bin malwieder dumm. Wollte obige Ersetzung mittels vbs für eine andere Anwendung gebrauchen, falle aber da auf die Nase, wenn der gesuchte Begriff nicht ganz am Anfang der Zeile steht.. Gibts da anstelle des "Left" noch eine andere Option die da etwas toleranter ist? face-wink
Gruß Haegar
Member: bastla
bastla Sep 22, 2008 at 19:42:58 (UTC)
Goto Top
Hallo Haegar75!

Wenn es genügt, dass der Suchbegriff irgendwo in der Zeile vorkommt:
>>%R% echo     If InStr(1,Zeilen(i),Suche,vbTextCompare)=0 Then
als Ersatz für die "If Left(..."-Zeile im Batch.

Grüße
bastla
Member: Haegar75
Haegar75 Sep 22, 2008 at 19:50:11 (UTC)
Goto Top
Danke! Bist ein Schatz! face-wink
Schönen Abend noch!