Batch. Suchen und Ersetzen in einer Zeile einer ini-Datei die ein ! enthält
Moin zusammen,
In einer ini-Datei sind Sektionen mit Schlüssel-Wert-Paaren in der Form von:
[logging]
logfilecount=10
loggingactive=true
loglevel=DEBUG
[catalog]
catalogfilecount=10
catalogpath=catalog
activecatalog=catalog.bin
[naming]
activescheme=Personen.xml
autoscan=false
namingservercheck=false
useclassification=true
[fileparameter]
picfiles=jpg!bmp!tif!tiff!gif!
vidfiles=avi!mpeg!mpg!
…. usw. vorhanden.
Beim Programmstart wird vor der Verwendung der ini-Datei auf dem Netzlaufwerk nach geänderten Schlüssel-Wert-Paaren geschaut. Das klappt bis auf die Wertpaare, die ein ! enthalten. Die ! verschwinden leider nach dem Skriptdurchlauf und sehen dann so aus:
[fileparameter]
picfiles=jpgbmptiftiffgif
vidfiles=avimpegmpg
Kann mir hier jemand weiterhelfen?
Anbei mein Skript:
In einer ini-Datei sind Sektionen mit Schlüssel-Wert-Paaren in der Form von:
[logging]
logfilecount=10
loggingactive=true
loglevel=DEBUG
[catalog]
catalogfilecount=10
catalogpath=catalog
activecatalog=catalog.bin
[naming]
activescheme=Personen.xml
autoscan=false
namingservercheck=false
useclassification=true
[fileparameter]
picfiles=jpg!bmp!tif!tiff!gif!
vidfiles=avi!mpeg!mpg!
…. usw. vorhanden.
Beim Programmstart wird vor der Verwendung der ini-Datei auf dem Netzlaufwerk nach geänderten Schlüssel-Wert-Paaren geschaut. Das klappt bis auf die Wertpaare, die ein ! enthalten. Die ! verschwinden leider nach dem Skriptdurchlauf und sehen dann so aus:
[fileparameter]
picfiles=jpgbmptiftiffgif
vidfiles=avimpegmpg
Kann mir hier jemand weiterhelfen?
Anbei mein Skript:
@echo off
setlocal enabledelayedexpansion
set "clientIniPath=C:\Programm\programm.ini"
set "computerName=%COMPUTERNAME%"
set "serverIniPath=\\Netzlaufwerk\%computerName%.ini"
if exist "%serverIniPath%" (
echo Datei %serverIniPath% existiert.
for /f "tokens=1* delims==" %%A in ('findstr /r /c:"=.*" "%serverIniPath%"') do (
set "serverKey=%%A"
set "serverValue=%%B"
set "found=0"
for /f "tokens=1* delims==" %%C in ('findstr /r /c:"=.*" "%clientIniPath%"') do (
if "%%C"=="!serverKey!" (
set "found=1"
if not "%%D"=="!serverValue!" (
echo Wert für !serverKey! wird überschrieben.
call :replaceLine "%clientIniPath%" "%%C=%%D" "%%C=!serverValue!"
)
)
)
if "!found!"=="0" (
echo !serverKey!=!serverValue! >> "%clientIniPath%"
)
)
) else (
echo Datei %serverIniPath% existiert nicht.
)
goto :eof
:replaceLine
set "file=%~1"
set "search=%~2"
set "replace=%~3"
set "tempFile=%file%.tmp"
(for /f "delims=" %%i in ('type "%file%"') do (
set "line=%%i"
if "!line!"=="%search%" (
echo %replace%
) else (
if "!line:~0,1!"=="[" (
echo.
echo %%i
) else (
echo %%i
)
)
)) > "%tempFile%"
move /y "%tempFile%" "%file%"
goto :eof
pause
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 93351255323
Url: https://administrator.de/forum/batch-suchen-und-ersetzen-in-einer-zeile-einer-ini-datei-die-ein-enthaelt-93351255323.html
Ausgedruckt am: 22.12.2024 um 06:12 Uhr
6 Kommentare
Neuester Kommentar
Moin,
wäre es nicht einfacher zu überprüfen, ob die ini auf dem Server anders ist und diese in dem Fall zu kopieren?
Etwa so:
Gruß Thomas
wäre es nicht einfacher zu überprüfen, ob die ini auf dem Server anders ist und diese in dem Fall zu kopieren?
Zitat von @silvereye:
Das klappt bis auf die Wertpaare, die ein ! enthalten. Die ! verschwinden leider nach dem Skriptdurchlauf und sehen dann so aus:
Du musst in dem Fall natürlich auf das "setlocal EnableDelayedExpansion" verzichten und stattdessen mit Funktionen arbeiten.Das klappt bis auf die Wertpaare, die ein ! enthalten. Die ! verschwinden leider nach dem Skriptdurchlauf und sehen dann so aus:
Etwa so:
@echo off
set "clientIniPath=C:\Programm\programm.ini"
set "serverIniPath=\\Netzlaufwerk\%computerName%.ini"
if exist "%serverIniPath%" (
echo Datei %serverIniPath% existiert.
for /f "tokens=1* delims==" %%A in ('findstr /r /c:"=.*" "%serverIniPath%"') do (
set found=0
for /f "tokens=1* delims==" %%C in ('findstr /r /c:"=.*" "%clientIniPath%"') do call :checkKey "%%~A" "%%~B" "%%~C" "%%~D"
call :checkFound && >>"%clientIniPath%" echo %%~A=%%~B
)
) else echo Datei %serverIniPath% existiert nicht.
goto :eof
:checkKey <ServerKey> <ServerValue> <ClientKey> <ClientValue>
if "%~3" == "%~1" (
set found=1
if not "%~4" == "%~2" (
echo Wert für %~1 wird überschrieben.
call :replaceLine "%clientIniPath%" "%~3=%~4" "%~3=%~2"
)
)
exit /b 0
:replaceLine
set "file=%~1"
set "search=%~2"
set "replace=%~3"
set "tempFile=%file%.tmp"
>"%tempFile%" (for /f "delims=" %%i in ('type "%file%"') do call :checkLine "%%~i")
move /y "%tempFile%" "%file%"
goto :eof
:checkLine <line>
set "line=%~1"
if "%line%"=="%search%" (
echo %replace%
) else (
if "%line:~0,1%"=="[" (
echo.
echo %~1
) else (
echo %~1
)
)
exit /b 0
:checkFound
exit /b %found%
Gruß Thomas
Die wie immer beste Idee hätte ich natürlich noch: Batch endlich begraben und stattdessen zeitgemäß Powershell nehmen...
$ClientFile = "C:\Programm\programm.ini"
$ServerFile = "\\Netzlaufwerk\${ENV:ComputerName}.ini"
function Read-Ini {
[CmdletBinding()]Param([string]$path)
$ini = [ordered]@{}
$section = ""
Foreach ($Line in Get-Content -Path $path) {
switch -RegEx ($line) {
"^\[(.+)\]$" {
$section = $Matches[1]
$ini.$section = [ordered]@{}
}
"^([^=]+)=(.*)$" {
$key,$value = $Matches[1,2]
$ini.$section.$key = $value
}
"^\s*$" {}
default {
$ini.$section.$_ = $NULL
}
}
}
Add-Member -Input $ini -MemberType ScriptMethod -Name ToArray -Value {
$content = Foreach ($section in $this.keys) {
"[$section]"
Foreach ($e in $this.$section.GetEnumerator()) {
if ($e.Value) {
"{0}={1}" -f $e.Key,$e.Value
} else {$e.Key}
}
""
}
$content[0..($content.count-2)]
}
return $ini
}
try {
$ErrorActionPreference = "stop"
$clientIni = Read-Ini $ClientFile
$ServerIni = Read-Ini $ServerFile
foreach ($section in $serverIni.keys) {
if ($clientIni.keys -notcontains $section) {
Write-Host "Ergänze Sektion: $section"
$clientIni.$section = $serverIni.$section
}
else {
Foreach ($key in $serverIni.$section.keys) {
if ($clientIni.$section.keys -notcontains $key) {
Write-Host "Ergänze Schlüssel in [${section}]: $key"
$clientIni.$section.$key = $serverIni.$section.$key
}
else {
if ($clientIni.$section.$key -ne $serverIni.$section.$key) {
Write-Host "Ändere Wert für ${key}"
$clientIni.$section.$key = $serverIni.$section.$key
}
}
}
}
}
$clientIni.ToArray() | Set-Content $clientFile
} catch {
Write-Host -ForegroundColor red $_.Exception.Message
Write-Host -ForegroundColor yellow -NoNewLine "`n --- Beliebige Taste zum Beenden --- "
[void][Console]::ReadKey($true)
}